Skip to content

Commit

Permalink
Merge f0278f5 into fbe1782
Browse files Browse the repository at this point in the history
  • Loading branch information
LagginTimes committed May 3, 2024
2 parents fbe1782 + f0278f5 commit 80beb31
Show file tree
Hide file tree
Showing 9 changed files with 375 additions and 379 deletions.
2 changes: 2 additions & 0 deletions crates/bdk/src/wallet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2419,6 +2419,7 @@ impl Wallet {
/// start a blockchain sync with a spk based blockchain client.
pub fn start_sync_with_revealed_spks(&self) -> SyncRequest {
SyncRequest::from_chain_tip(self.chain.tip())
.cache_graph_txs(self.tx_graph())
.populate_with_revealed_spks(&self.indexed_graph.index, ..)
}

Expand All @@ -2432,6 +2433,7 @@ impl Wallet {
/// in which the list of used scripts is not known.
pub fn start_full_scan(&self) -> FullScanRequest<KeychainKind> {
FullScanRequest::from_keychain_txout_index(self.chain.tip(), &self.indexed_graph.index)
.cache_graph_txs(self.tx_graph())
}
}

Expand Down
73 changes: 67 additions & 6 deletions crates/chain/src/spk_client.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
//! 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 alloc::{boxed::Box, collections::BTreeMap, vec::Vec};
use bitcoin::{OutPoint, Script, ScriptBuf, Txid};

use crate::{local_chain::CheckPoint, ConfirmationTimeHeightAnchor, TxGraph};
/// A cache of [`Arc`]-wrapped full transactions, identified by their [`Txid`]s.
///
/// This is used by the chain-source to avoid re-fetching full transactions.
pub type TxCache = HashMap<Txid, Arc<Transaction>>;

/// Data required to perform a spk-based blockchain client sync.
///
Expand All @@ -17,6 +24,8 @@ pub struct SyncRequest {
///
/// [`LocalChain::tip`]: crate::local_chain::LocalChain::tip
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.
pub spks: Box<dyn ExactSizeIterator<Item = ScriptBuf> + Send>,
/// Transactions with these txids.
Expand All @@ -30,12 +39,37 @@ impl SyncRequest {
pub fn from_chain_tip(cp: CheckPoint) -> Self {
Self {
chain_tip: cp,
tx_cache: TxCache::new(),
spks: Box::new(core::iter::empty()),
txids: Box::new(core::iter::empty()),
outpoints: Box::new(core::iter::empty()),
}
}

/// Add to the [`Transaction`] cache that allows the chain source to avoid re-fetching full
/// transactions.
///
/// 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 [`Transaction`] cache.
///
/// 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.
///
/// This consumes the [`SyncRequest`] and returns the updated one.
Expand Down Expand Up @@ -194,6 +228,8 @@ pub struct FullScanRequest<K> {
///
/// [`LocalChain::tip`]: crate::local_chain::LocalChain::tip
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.
pub spks_by_keychain: BTreeMap<K, Box<dyn Iterator<Item = (u32, ScriptBuf)> + Send>>,
}
Expand All @@ -204,10 +240,35 @@ impl<K: Ord + Clone> FullScanRequest<K> {
pub fn from_chain_tip(chain_tip: CheckPoint) -> Self {
Self {
chain_tip,
tx_cache: TxCache::new(),
spks_by_keychain: BTreeMap::new(),
}
}

/// Add to the [`Transaction`] cache that allows the chain source to avoid re-fetching full
/// transactions.
///
/// 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 [`Transaction`] cache.
///
/// 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`.
///
/// Unbounded script pubkey iterators for each keychain (`K`) are extracted using
Expand Down Expand Up @@ -316,9 +377,9 @@ impl<K: Ord + Clone> FullScanRequest<K> {
/// Data returned from a spk-based blockchain client full scan.
///
/// See also [`FullScanRequest`].
pub struct FullScanResult<K> {
pub struct FullScanResult<K, A = ConfirmationTimeHeightAnchor> {
/// The update to apply to the receiving [`LocalChain`](crate::local_chain::LocalChain).
pub graph_update: TxGraph<ConfirmationTimeHeightAnchor>,
pub graph_update: TxGraph<A>,
/// The update to apply to the receiving [`TxGraph`].
pub chain_update: CheckPoint,
/// Last active indices for the corresponding keychains (`K`).
Expand Down
10 changes: 5 additions & 5 deletions crates/chain/src/tx_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -516,12 +516,12 @@ impl<A: Clone + Ord> TxGraph<A> {
/// Inserts the given transaction into [`TxGraph`].
///
/// The [`ChangeSet`] returned will be empty if `tx` already exists.
pub fn insert_tx(&mut self, tx: Transaction) -> ChangeSet<A> {
pub fn insert_tx<T: Into<Arc<Transaction>>>(&mut self, tx: T) -> ChangeSet<A> {
let tx = tx.into();
let mut update = Self::default();
update.txs.insert(
tx.txid(),
(TxNodeInternal::Whole(tx.into()), BTreeSet::new(), 0),
);
update
.txs
.insert(tx.txid(), (TxNodeInternal::Whole(tx), BTreeSet::new(), 0));
self.apply_update(update)
}

Expand Down
2 changes: 1 addition & 1 deletion crates/electrum/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ readme = "README.md"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
bdk_chain = { path = "../chain", version = "0.13.0", default-features = false }
bdk_chain = { path = "../chain", version = "0.13.0" }
electrum-client = { version = "0.19" }
#rustls = { version = "=0.21.1", optional = true, features = ["dangerous_configuration"] }

Expand Down

0 comments on commit 80beb31

Please sign in to comment.