Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions crates/bitcoind_rpc/tests/test_emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ use std::collections::{BTreeMap, BTreeSet};
use bdk_bitcoind_rpc::Emitter;
use bdk_chain::{
bitcoin::{Address, Amount, Txid},
keychain::Balance,
local_chain::{CheckPoint, LocalChain},
Append, BlockId, IndexedTxGraph, SpkTxOutIndex,
Append, Balance, BlockId, IndexedTxGraph, SpkTxOutIndex,
};
use bdk_testenv::{anyhow, TestEnv};
use bitcoin::{hashes::Hash, Block, OutPoint, ScriptBuf, WScriptHash};
Expand Down
23 changes: 1 addition & 22 deletions crates/chain/src/keychain.rs → crates/chain/src/balance.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,4 @@
//! Module for keychain related structures.
//!
//! A keychain here is a set of application-defined indexes for a miniscript descriptor where we can
//! derive script pubkeys at a particular derivation index. The application's index is simply
//! anything that implements `Ord`.
//!
//! [`KeychainTxOutIndex`] indexes script pubkeys of keychains and scans in relevant outpoints (that
//! has a `txout` containing an indexed script pubkey). Internally, this uses [`SpkTxOutIndex`], but
//! also maintains "revealed" and "lookahead" index counts per keychain.
//!
//! [`SpkTxOutIndex`]: crate::SpkTxOutIndex

#[cfg(feature = "miniscript")]
mod txout_index;
use bitcoin::{Amount, ScriptBuf};
#[cfg(feature = "miniscript")]
pub use txout_index::*;
use bitcoin::Amount;

/// Balance, differentiated into various categories.
#[derive(Debug, PartialEq, Eq, Clone, Default)]
Expand Down Expand Up @@ -49,11 +33,6 @@ impl Balance {
}
}

/// A tuple of keychain index and `T` representing the indexed value.
pub type Indexed<T> = (u32, T);
/// A tuple of keychain `K`, derivation index (`u32`) and a `T` associated with them.
pub type KeychainIndexed<K, T> = ((K, u32), T);

impl core::fmt::Display for Balance {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(
Expand Down
14 changes: 9 additions & 5 deletions crates/chain/src/changeset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ pub struct CombinedChangeSet<K, A> {
/// Changes to the [`LocalChain`](crate::local_chain::LocalChain).
pub chain: crate::local_chain::ChangeSet,
/// Changes to [`IndexedTxGraph`](crate::indexed_tx_graph::IndexedTxGraph).
pub indexed_tx_graph: crate::indexed_tx_graph::ChangeSet<A, crate::keychain::ChangeSet<K>>,
pub indexed_tx_graph:
crate::indexed_tx_graph::ChangeSet<A, crate::indexer::keychain_txout::ChangeSet<K>>,
/// Stores the network type of the transaction data.
pub network: Option<bitcoin::Network>,
}
Expand Down Expand Up @@ -62,11 +63,14 @@ impl<K, A> From<crate::local_chain::ChangeSet> for CombinedChangeSet<K, A> {
}

#[cfg(feature = "miniscript")]
impl<K, A> From<crate::indexed_tx_graph::ChangeSet<A, crate::keychain::ChangeSet<K>>>
impl<K, A> From<crate::indexed_tx_graph::ChangeSet<A, crate::indexer::keychain_txout::ChangeSet<K>>>
for CombinedChangeSet<K, A>
{
fn from(
indexed_tx_graph: crate::indexed_tx_graph::ChangeSet<A, crate::keychain::ChangeSet<K>>,
indexed_tx_graph: crate::indexed_tx_graph::ChangeSet<
A,
crate::indexer::keychain_txout::ChangeSet<K>,
>,
) -> Self {
Self {
indexed_tx_graph,
Expand All @@ -76,8 +80,8 @@ impl<K, A> From<crate::indexed_tx_graph::ChangeSet<A, crate::keychain::ChangeSet
}

#[cfg(feature = "miniscript")]
impl<K, A> From<crate::keychain::ChangeSet<K>> for CombinedChangeSet<K, A> {
fn from(indexer: crate::keychain::ChangeSet<K>) -> Self {
impl<K, A> From<crate::indexer::keychain_txout::ChangeSet<K>> for CombinedChangeSet<K, A> {
fn from(indexer: crate::indexer::keychain_txout::ChangeSet<K>) -> Self {
Self {
indexed_tx_graph: crate::indexed_tx_graph::ChangeSet {
indexer,
Expand Down
32 changes: 5 additions & 27 deletions crates/chain/src/indexed_tx_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use bitcoin::{Block, OutPoint, Transaction, TxOut, Txid};

use crate::{
tx_graph::{self, TxGraph},
Anchor, AnchorFromBlockPosition, Append, BlockId,
Anchor, AnchorFromBlockPosition, Append, BlockId, Indexer,
};

/// The [`IndexedTxGraph`] combines a [`TxGraph`] and an [`Indexer`] implementation.
Expand Down Expand Up @@ -320,39 +320,17 @@ impl<A, IA: Default> From<tx_graph::ChangeSet<A>> for ChangeSet<A, IA> {
}

#[cfg(feature = "miniscript")]
impl<A, K> From<crate::keychain::ChangeSet<K>> for ChangeSet<A, crate::keychain::ChangeSet<K>> {
fn from(indexer: crate::keychain::ChangeSet<K>) -> Self {
impl<A, K> From<crate::indexer::keychain_txout::ChangeSet<K>>
for ChangeSet<A, crate::indexer::keychain_txout::ChangeSet<K>>
{
fn from(indexer: crate::indexer::keychain_txout::ChangeSet<K>) -> Self {
Self {
graph: Default::default(),
indexer,
}
}
}

/// Utilities for indexing transaction data.
///
/// Types which implement this trait can be used to construct an [`IndexedTxGraph`].
/// This trait's methods should rarely be called directly.
pub trait Indexer {
/// The resultant "changeset" when new transaction data is indexed.
type ChangeSet;

/// Scan and index the given `outpoint` and `txout`.
fn index_txout(&mut self, outpoint: OutPoint, txout: &TxOut) -> Self::ChangeSet;

/// Scans a transaction for relevant outpoints, which are stored and indexed internally.
fn index_tx(&mut self, tx: &Transaction) -> Self::ChangeSet;

/// Apply changeset to itself.
fn apply_changeset(&mut self, changeset: Self::ChangeSet);

/// Determines the [`ChangeSet`] between `self` and an empty [`Indexer`].
fn initial_changeset(&self) -> Self::ChangeSet;

/// Determines whether the transaction should be included in the index.
fn is_tx_relevant(&self, tx: &Transaction) -> bool;
}

impl<A, I> AsRef<TxGraph<A>> for IndexedTxGraph<A, I> {
fn as_ref(&self) -> &TxGraph<A> {
&self.graph
Expand Down
33 changes: 33 additions & 0 deletions crates/chain/src/indexer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//! [`Indexer`] provides utilities for indexing transaction data.

use bitcoin::{OutPoint, Transaction, TxOut};
Comment thread
notmandatory marked this conversation as resolved.

#[cfg(feature = "miniscript")]
pub mod keychain_txout;
pub mod spk_txout;

/// Utilities for indexing transaction data.
///
/// Types which implement this trait can be used to construct an [`IndexedTxGraph`].
/// This trait's methods should rarely be called directly.
///
/// [`IndexedTxGraph`]: crate::IndexedTxGraph
pub trait Indexer {
/// The resultant "changeset" when new transaction data is indexed.
type ChangeSet;

/// Scan and index the given `outpoint` and `txout`.
fn index_txout(&mut self, outpoint: OutPoint, txout: &TxOut) -> Self::ChangeSet;

/// Scans a transaction for relevant outpoints, which are stored and indexed internally.
fn index_tx(&mut self, tx: &Transaction) -> Self::ChangeSet;

/// Apply changeset to itself.
fn apply_changeset(&mut self, changeset: Self::ChangeSet);

/// Determines the [`ChangeSet`](Indexer::ChangeSet) between `self` and an empty [`Indexer`].
fn initial_changeset(&self) -> Self::ChangeSet;

/// Determines whether the transaction should be included in the index.
fn is_tx_relevant(&self, tx: &Transaction) -> bool;
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
//! [`KeychainTxOutIndex`] controls how script pubkeys are revealed for multiple keychains and
//! indexes [`TxOut`]s with them.

use crate::{
collections::*,
indexed_tx_graph::Indexer,
miniscript::{Descriptor, DescriptorPublicKey},
spk_iter::BIP32_MAX_INDEX,
DescriptorExt, DescriptorId, SpkIterator, SpkTxOutIndex,
DescriptorExt, DescriptorId, Indexed, Indexer, KeychainIndexed, SpkIterator, SpkTxOutIndex,
};
use alloc::{borrow::ToOwned, vec::Vec};
use bitcoin::{Amount, OutPoint, Script, SignedAmount, Transaction, TxOut, Txid};
use bitcoin::{Amount, OutPoint, Script, ScriptBuf, SignedAmount, Transaction, TxOut, Txid};
use core::{
fmt::Debug,
ops::{Bound, RangeBounds},
};

use super::*;
use crate::Append;

/// The default lookahead for a [`KeychainTxOutIndex`]
Expand Down Expand Up @@ -73,7 +74,7 @@ pub const DEFAULT_LOOKAHEAD: u32 = 25;
/// ## Synopsis
///
/// ```
/// use bdk_chain::keychain::KeychainTxOutIndex;
/// use bdk_chain::indexer::keychain_txout::KeychainTxOutIndex;
/// # use bdk_chain::{ miniscript::{Descriptor, DescriptorPublicKey} };
/// # use core::str::FromStr;
///
Expand All @@ -98,7 +99,7 @@ pub const DEFAULT_LOOKAHEAD: u32 = 25;
/// let _ = txout_index.insert_descriptor(MyKeychain::MyAppUser { user_id: 42 }, descriptor_42)?;
///
/// let new_spk_for_user = txout_index.reveal_next_spk(&MyKeychain::MyAppUser{ user_id: 42 });
/// # Ok::<_, bdk_chain::keychain::InsertDescriptorError<_>>(())
/// # Ok::<_, bdk_chain::indexer::keychain_txout::InsertDescriptorError<_>>(())
/// ```
///
/// [`Ord`]: core::cmp::Ord
Expand Down Expand Up @@ -859,8 +860,7 @@ impl<K: core::fmt::Debug> std::error::Error for InsertDescriptorError<K> {}
/// `keychains_added` is *not* monotone, once it is set any attempt to change it is subject to the
/// same *one-to-one* keychain <-> descriptor mapping invariant as [`KeychainTxOutIndex`] itself.
///
/// [`KeychainTxOutIndex`]: crate::keychain::KeychainTxOutIndex
/// [`apply_changeset`]: crate::keychain::KeychainTxOutIndex::apply_changeset
/// [`apply_changeset`]: KeychainTxOutIndex::apply_changeset
/// [`append`]: Self::append
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
//! [`SpkTxOutIndex`] is an index storing [`TxOut`]s that have a script pubkey that matches those in a list.

use core::ops::RangeBounds;

use crate::{
collections::{hash_map::Entry, BTreeMap, BTreeSet, HashMap},
indexed_tx_graph::Indexer,
Indexer,
};
use bitcoin::{Amount, OutPoint, Script, ScriptBuf, SignedAmount, Transaction, TxOut, Txid};

Expand Down
14 changes: 10 additions & 4 deletions crates/chain/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,15 @@
#![warn(missing_docs)]

pub use bitcoin;
mod spk_txout_index;
pub use spk_txout_index::*;
mod balance;
pub use balance::*;
mod chain_data;
pub use chain_data::*;
pub mod indexed_tx_graph;
pub use indexed_tx_graph::IndexedTxGraph;
pub mod keychain;
pub use keychain::{Indexed, KeychainIndexed};
pub mod indexer;
pub use indexer::spk_txout::*;
pub use indexer::Indexer;
pub mod local_chain;
mod tx_data_traits;
pub mod tx_graph;
Expand Down Expand Up @@ -98,3 +99,8 @@ pub mod collections {

/// How many confirmations are needed f or a coinbase output to be spent.
pub const COINBASE_MATURITY: u32 = 100;

/// A tuple of keychain index and `T` representing the indexed value.
pub type Indexed<T> = (u32, T);
/// A tuple of keychain `K`, derivation index (`u32`) and a `T` associated with them.
pub type KeychainIndexed<K, T> = ((K, u32), T);
9 changes: 4 additions & 5 deletions crates/chain/src/spk_client.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
//! Helper types for spk-based blockchain clients.

use crate::{
collections::BTreeMap, keychain::Indexed, local_chain::CheckPoint,
ConfirmationTimeHeightAnchor, TxGraph,
collections::BTreeMap, local_chain::CheckPoint, ConfirmationTimeHeightAnchor, Indexed, TxGraph,
};
use alloc::boxed::Box;
use bitcoin::{OutPoint, Script, ScriptBuf, Txid};
Expand Down Expand Up @@ -160,7 +159,7 @@ impl SyncRequest {
#[must_use]
pub fn populate_with_revealed_spks<K: Clone + Ord + core::fmt::Debug + Send + Sync>(
self,
index: &crate::keychain::KeychainTxOutIndex<K>,
index: &crate::indexer::keychain_txout::KeychainTxOutIndex<K>,
spk_range: impl core::ops::RangeBounds<K>,
) -> Self {
use alloc::borrow::ToOwned;
Expand Down Expand Up @@ -216,12 +215,12 @@ impl<K: Ord + Clone> FullScanRequest<K> {
/// [`KeychainTxOutIndex::all_unbounded_spk_iters`] and is used to populate the
/// [`FullScanRequest`].
///
/// [`KeychainTxOutIndex::all_unbounded_spk_iters`]: crate::keychain::KeychainTxOutIndex::all_unbounded_spk_iters
/// [`KeychainTxOutIndex::all_unbounded_spk_iters`]: crate::indexer::keychain_txout::KeychainTxOutIndex::all_unbounded_spk_iters
#[cfg(feature = "miniscript")]
#[must_use]
pub fn from_keychain_txout_index(
chain_tip: CheckPoint,
index: &crate::keychain::KeychainTxOutIndex<K>,
index: &crate::indexer::keychain_txout::KeychainTxOutIndex<K>,
) -> Self
where
K: core::fmt::Debug,
Expand Down
4 changes: 2 additions & 2 deletions crates/chain/src/spk_iter.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::{
bitcoin::{secp256k1::Secp256k1, ScriptBuf},
keychain::Indexed,
miniscript::{Descriptor, DescriptorPublicKey},
Indexed,
};
use core::{borrow::Borrow, ops::Bound, ops::RangeBounds};

Expand Down Expand Up @@ -137,7 +137,7 @@ where
mod test {
use crate::{
bitcoin::secp256k1::Secp256k1,
keychain::KeychainTxOutIndex,
indexer::keychain_txout::KeychainTxOutIndex,
miniscript::{Descriptor, DescriptorPublicKey},
spk_iter::{SpkIterator, BIP32_MAX_INDEX},
};
Expand Down
3 changes: 1 addition & 2 deletions crates/chain/src/tx_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,7 @@
//! [`insert_txout`]: TxGraph::insert_txout

use crate::{
collections::*, keychain::Balance, Anchor, Append, BlockId, ChainOracle, ChainPosition,
FullTxOut,
collections::*, Anchor, Append, Balance, BlockId, ChainOracle, ChainPosition, FullTxOut,
};
use alloc::collections::vec_deque::VecDeque;
use alloc::sync::Arc;
Expand Down
9 changes: 5 additions & 4 deletions crates/chain/tests/test_indexed_tx_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ use std::{collections::BTreeSet, sync::Arc};
use crate::common::DESCRIPTORS;
use bdk_chain::{
indexed_tx_graph::{self, IndexedTxGraph},
keychain::{self, Balance, KeychainTxOutIndex},
indexer::keychain_txout::KeychainTxOutIndex,
local_chain::LocalChain,
tx_graph, Append, ChainPosition, ConfirmationHeightAnchor, DescriptorExt,
tx_graph, Append, Balance, ChainPosition, ConfirmationHeightAnchor, DescriptorExt,
};
use bitcoin::{
secp256k1::Secp256k1, Amount, OutPoint, Script, ScriptBuf, Transaction, TxIn, TxOut,
Expand All @@ -26,6 +26,7 @@ use miniscript::Descriptor;
/// agnostic.
#[test]
fn insert_relevant_txs() {
use bdk_chain::indexer::keychain_txout;
let (descriptor, _) = Descriptor::parse_descriptor(&Secp256k1::signing_only(), DESCRIPTORS[0])
.expect("must be valid");
let spk_0 = descriptor.at_derivation_index(0).unwrap().script_pubkey();
Expand Down Expand Up @@ -76,7 +77,7 @@ fn insert_relevant_txs() {
txs: txs.iter().cloned().map(Arc::new).collect(),
..Default::default()
},
indexer: keychain::ChangeSet {
indexer: keychain_txout::ChangeSet {
last_revealed: [(descriptor.descriptor_id(), 9_u32)].into(),
keychains_added: [].into(),
},
Expand All @@ -90,7 +91,7 @@ fn insert_relevant_txs() {
// The initial changeset will also contain info about the keychain we added
let initial_changeset = indexed_tx_graph::ChangeSet {
graph: changeset.graph,
indexer: keychain::ChangeSet {
indexer: keychain_txout::ChangeSet {
last_revealed: changeset.indexer.last_revealed,
keychains_added: [((), descriptor)].into(),
},
Expand Down
Loading