From de254070624c02a7efed232e72afb490f0d4d6eb Mon Sep 17 00:00:00 2001 From: Daniela Brozzoni Date: Mon, 7 Aug 2023 17:43:17 +0200 Subject: [PATCH] refactor!(chain): Unify ChangeSet nomenclature This commit renames: - indexed_tx_graph::IndexedAdditions -> indexed_tx_graph::ChangeSet - tx_graph::Additions -> tx_graph::ChangeSet - keychain::DerivationAdditions -> keychain::ChangeSet - CanonicalTx::node -> CanonicalTx::tx_node - CanonicalTx::observed_as -> CanonicalTx::chain_position This commit also changes the visibility of TxGraph::determine_changeset to be pub(crate) This commit removes: - `TxGraph::insert_txout_preview` - `TxGraph::insert_tx_preview` - `insert_anchor_preview` - `insert_seen_at_preview` Solves #1022 --- crates/bdk/src/wallet/export.rs | 9 +- crates/bdk/src/wallet/mod.rs | 46 +++-- crates/bdk/tests/wallet.rs | 4 +- crates/chain/src/indexed_tx_graph.rs | 112 +++++------ crates/chain/src/keychain.rs | 43 ++-- crates/chain/src/keychain/txout_index.rs | 70 ++++--- crates/chain/src/spk_txout_index.rs | 8 +- crates/chain/src/tx_graph.rs | 190 +++++++----------- crates/chain/tests/test_indexed_tx_graph.rs | 13 +- .../chain/tests/test_keychain_txout_index.rs | 38 ++-- crates/chain/tests/test_tx_graph.rs | 34 ++-- crates/electrum/src/electrum_ext.rs | 16 +- example-crates/example_cli/src/lib.rs | 34 ++-- example-crates/example_electrum/src/main.rs | 25 +-- 14 files changed, 300 insertions(+), 342 deletions(-) diff --git a/crates/bdk/src/wallet/export.rs b/crates/bdk/src/wallet/export.rs index 270d734013..f2d656891e 100644 --- a/crates/bdk/src/wallet/export.rs +++ b/crates/bdk/src/wallet/export.rs @@ -126,13 +126,12 @@ impl FullyNodedExport { Self::is_compatible_with_core(&descriptor)?; let blockheight = if include_blockheight { - wallet - .transactions() - .next() - .map_or(0, |canonical_tx| match canonical_tx.observed_as { + wallet.transactions().next().map_or(0, |canonical_tx| { + match canonical_tx.chain_position { bdk_chain::ChainPosition::Confirmed(a) => a.confirmation_height, bdk_chain::ChainPosition::Unconfirmed(_) => 0, - }) + } + }) } else { 0 }; diff --git a/crates/bdk/src/wallet/mod.rs b/crates/bdk/src/wallet/mod.rs index 2ef69f317f..c0d4b5c073 100644 --- a/crates/bdk/src/wallet/mod.rs +++ b/crates/bdk/src/wallet/mod.rs @@ -21,7 +21,7 @@ use alloc::{ }; pub use bdk_chain::keychain::Balance; use bdk_chain::{ - indexed_tx_graph::IndexedAdditions, + indexed_tx_graph, keychain::{KeychainTxOutIndex, LocalChangeSet, LocalUpdate}, local_chain::{self, CannotConnectError, CheckPoint, CheckPointIter, LocalChain}, tx_graph::{CanonicalTx, TxGraph}, @@ -247,7 +247,7 @@ impl Wallet { let changeset = db.load_from_persistence().map_err(NewError::Persist)?; chain.apply_changeset(&changeset.chain_changeset); - indexed_graph.apply_additions(changeset.indexed_additions); + indexed_graph.apply_changeset(changeset.indexed_changeset); let persist = Persist::new(db); @@ -320,14 +320,14 @@ impl Wallet { { let keychain = self.map_keychain(keychain); let txout_index = &mut self.indexed_graph.index; - let (index, spk, additions) = match address_index { + let (index, spk, changeset) = match address_index { AddressIndex::New => { - let ((index, spk), index_additions) = txout_index.reveal_next_spk(&keychain); - (index, spk.into(), Some(index_additions)) + let ((index, spk), index_changeset) = txout_index.reveal_next_spk(&keychain); + (index, spk.into(), Some(index_changeset)) } AddressIndex::LastUnused => { - let ((index, spk), index_additions) = txout_index.next_unused_spk(&keychain); - (index, spk.into(), Some(index_additions)) + let ((index, spk), index_changeset) = txout_index.next_unused_spk(&keychain); + (index, spk.into(), Some(index_changeset)) } AddressIndex::Peek(index) => { let (index, spk) = txout_index @@ -339,9 +339,11 @@ impl Wallet { } }; - if let Some(additions) = additions { + if let Some(changeset) = changeset { self.persist - .stage(ChangeSet::from(IndexedAdditions::from(additions))); + .stage(ChangeSet::from(indexed_tx_graph::ChangeSet::from( + changeset, + ))); self.persist.commit()?; } @@ -436,12 +438,12 @@ impl Wallet { let graph = self.indexed_graph.graph(); let canonical_tx = CanonicalTx { - observed_as: graph.get_chain_position( + chain_position: graph.get_chain_position( &self.chain, self.chain.tip().map(|cp| cp.block_id()).unwrap_or_default(), txid, )?, - node: graph.get_tx_node(txid)?, + tx_node: graph.get_tx_node(txid)?, }; Some(new_tx_details( @@ -889,12 +891,14 @@ impl Wallet { Some(ref drain_recipient) => drain_recipient.clone(), None => { let change_keychain = self.map_keychain(KeychainKind::Internal); - let ((index, spk), index_additions) = + let ((index, spk), index_changeset) = self.indexed_graph.index.next_unused_spk(&change_keychain); let spk = spk.into(); self.indexed_graph.index.mark_used(&change_keychain, index); self.persist - .stage(ChangeSet::from(IndexedAdditions::from(index_additions))); + .stage(ChangeSet::from(indexed_tx_graph::ChangeSet::from( + index_changeset, + ))); self.persist.commit().expect("TODO"); spk } @@ -1286,7 +1290,7 @@ impl Wallet { .indexed_graph .graph() .get_chain_position(&self.chain, chain_tip, input.previous_output.txid) - .map(|observed_as| match observed_as { + .map(|chain_position| match chain_position { ChainPosition::Confirmed(a) => a.confirmation_height, ChainPosition::Unconfirmed(_) => u32::MAX, }); @@ -1469,7 +1473,7 @@ impl Wallet { .graph() .get_chain_position(&self.chain, chain_tip, txid) { - Some(observed_as) => observed_as.cloned().into(), + Some(chain_position) => chain_position.cloned().into(), None => return false, }; @@ -1716,11 +1720,13 @@ impl Wallet { D: PersistBackend, { let mut changeset = ChangeSet::from(self.chain.apply_update(update.chain)?); - let (_, index_additions) = self + let (_, index_changeset) = self .indexed_graph .index .reveal_to_target_multi(&update.last_active_indices); - changeset.append(ChangeSet::from(IndexedAdditions::from(index_additions))); + changeset.append(ChangeSet::from(indexed_tx_graph::ChangeSet::from( + index_changeset, + ))); changeset.append(ChangeSet::from( self.indexed_graph.apply_update(update.graph), )); @@ -1827,7 +1833,7 @@ fn new_tx_details( ) -> TransactionDetails { let graph = indexed_graph.graph(); let index = &indexed_graph.index; - let tx = canonical_tx.node.tx; + let tx = canonical_tx.tx_node.tx; let received = tx .output @@ -1867,11 +1873,11 @@ fn new_tx_details( TransactionDetails { transaction: if include_raw { Some(tx.clone()) } else { None }, - txid: canonical_tx.node.txid, + txid: canonical_tx.tx_node.txid, received, sent, fee, - confirmation_time: canonical_tx.observed_as.cloned().into(), + confirmation_time: canonical_tx.chain_position.cloned().into(), } } diff --git a/crates/bdk/tests/wallet.rs b/crates/bdk/tests/wallet.rs index 396b727e58..14167ba8d1 100644 --- a/crates/bdk/tests/wallet.rs +++ b/crates/bdk/tests/wallet.rs @@ -1571,7 +1571,7 @@ fn test_bump_fee_remove_output_manually_selected_only() { .transactions() .last() .unwrap() - .observed_as + .chain_position .cloned() .into(), ) @@ -1621,7 +1621,7 @@ fn test_bump_fee_add_input() { .transactions() .last() .unwrap() - .observed_as + .chain_position .cloned() .into(); wallet.insert_tx(init_tx, pos).unwrap(); diff --git a/crates/chain/src/indexed_tx_graph.rs b/crates/chain/src/indexed_tx_graph.rs index 730b04340c..ac7d32a12f 100644 --- a/crates/chain/src/indexed_tx_graph.rs +++ b/crates/chain/src/indexed_tx_graph.rs @@ -6,8 +6,8 @@ use alloc::vec::Vec; use bitcoin::{OutPoint, Transaction, TxOut}; use crate::{ - keychain::DerivationAdditions, - tx_graph::{Additions, TxGraph}, + keychain, + tx_graph::{self, TxGraph}, Anchor, Append, }; @@ -46,47 +46,47 @@ impl IndexedTxGraph { } impl IndexedTxGraph { - /// Applies the [`IndexedAdditions`] to the [`IndexedTxGraph`]. - pub fn apply_additions(&mut self, additions: IndexedAdditions) { - let IndexedAdditions { - graph_additions, - index_additions, - } = additions; + /// Applies the [`ChangeSet`] to the [`IndexedTxGraph`]. + pub fn apply_changeset(&mut self, changeset: ChangeSet) { + let ChangeSet { + graph_changeset, + index_changeset, + } = changeset; - self.index.apply_additions(index_additions); + self.index.apply_changeset(index_changeset); - for tx in &graph_additions.txs { + for tx in &graph_changeset.txs { self.index.index_tx(tx); } - for (&outpoint, txout) in &graph_additions.txouts { + for (&outpoint, txout) in &graph_changeset.txouts { self.index.index_txout(outpoint, txout); } - self.graph.apply_additions(graph_additions); + self.graph.apply_changeset(graph_changeset); } } impl IndexedTxGraph where - I::Additions: Default + Append, + I::ChangeSet: Default + Append, { /// Apply an `update` directly. /// - /// `update` is a [`TxGraph`] and the resultant changes is returned as [`IndexedAdditions`]. - pub fn apply_update(&mut self, update: TxGraph) -> IndexedAdditions { - let graph_additions = self.graph.apply_update(update); + /// `update` is a [`TxGraph`] and the resultant changes is returned as [`ChangeSet`]. + pub fn apply_update(&mut self, update: TxGraph) -> ChangeSet { + let graph_changeset = self.graph.apply_update(update); - let mut index_additions = I::Additions::default(); - for added_tx in &graph_additions.txs { - index_additions.append(self.index.index_tx(added_tx)); + let mut index_changeset = I::ChangeSet::default(); + for added_tx in &graph_changeset.txs { + index_changeset.append(self.index.index_tx(added_tx)); } - for (&added_outpoint, added_txout) in &graph_additions.txouts { - index_additions.append(self.index.index_txout(added_outpoint, added_txout)); + for (&added_outpoint, added_txout) in &graph_changeset.txouts { + index_changeset.append(self.index.index_txout(added_outpoint, added_txout)); } - IndexedAdditions { - graph_additions, - index_additions, + ChangeSet { + graph_changeset, + index_changeset, } } @@ -95,7 +95,7 @@ where &mut self, outpoint: OutPoint, txout: &TxOut, - ) -> IndexedAdditions { + ) -> ChangeSet { let mut update = TxGraph::::default(); let _ = update.insert_txout(outpoint, txout.clone()); self.apply_update(update) @@ -110,7 +110,7 @@ where tx: &Transaction, anchors: impl IntoIterator, seen_at: Option, - ) -> IndexedAdditions { + ) -> ChangeSet { let txid = tx.txid(); let mut update = TxGraph::::default(); @@ -138,20 +138,20 @@ where &mut self, txs: impl IntoIterator)>, seen_at: Option, - ) -> IndexedAdditions { + ) -> ChangeSet { // The algorithm below allows for non-topologically ordered transactions by using two loops. // This is achieved by: // 1. insert all txs into the index. If they are irrelevant then that's fine it will just // not store anything about them. // 2. decide whether to insert them into the graph depending on whether `is_tx_relevant` // returns true or not. (in a second loop). - let mut additions = IndexedAdditions::::default(); + let mut changeset = ChangeSet::::default(); let mut transactions = Vec::new(); for (tx, anchors) in txs.into_iter() { - additions.index_additions.append(self.index.index_tx(tx)); + changeset.index_changeset.append(self.index.index_tx(tx)); transactions.push((tx, anchors)); } - additions.append( + changeset.append( transactions .into_iter() .filter_map(|(tx, anchors)| match self.index.is_tx_relevant(tx) { @@ -163,7 +163,7 @@ where acc }), ); - additions + changeset } } @@ -181,64 +181,64 @@ where ) )] #[must_use] -pub struct IndexedAdditions { - /// [`TxGraph`] additions. - pub graph_additions: Additions, - /// [`Indexer`] additions. - pub index_additions: IA, +pub struct ChangeSet { + /// [`TxGraph`] changeset. + pub graph_changeset: tx_graph::ChangeSet, + /// [`Indexer`] changeset. + pub index_changeset: IA, } -impl Default for IndexedAdditions { +impl Default for ChangeSet { fn default() -> Self { Self { - graph_additions: Default::default(), - index_additions: Default::default(), + graph_changeset: Default::default(), + index_changeset: Default::default(), } } } -impl Append for IndexedAdditions { +impl Append for ChangeSet { fn append(&mut self, other: Self) { - self.graph_additions.append(other.graph_additions); - self.index_additions.append(other.index_additions); + self.graph_changeset.append(other.graph_changeset); + self.index_changeset.append(other.index_changeset); } fn is_empty(&self) -> bool { - self.graph_additions.is_empty() && self.index_additions.is_empty() + self.graph_changeset.is_empty() && self.index_changeset.is_empty() } } -impl From> for IndexedAdditions { - fn from(graph_additions: Additions) -> Self { +impl From> for ChangeSet { + fn from(graph_changeset: tx_graph::ChangeSet) -> Self { Self { - graph_additions, + graph_changeset, ..Default::default() } } } -impl From> for IndexedAdditions> { - fn from(index_additions: DerivationAdditions) -> Self { +impl From> for ChangeSet> { + fn from(index_changeset: keychain::ChangeSet) -> Self { Self { - graph_additions: Default::default(), - index_additions, + graph_changeset: Default::default(), + index_changeset, } } } /// Represents a structure that can index transaction data. pub trait Indexer { - /// The resultant "additions" when new transaction data is indexed. - type Additions; + /// 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::Additions; + fn index_txout(&mut self, outpoint: OutPoint, txout: &TxOut) -> Self::ChangeSet; /// Scan and index the given transaction. - fn index_tx(&mut self, tx: &Transaction) -> Self::Additions; + fn index_tx(&mut self, tx: &Transaction) -> Self::ChangeSet; - /// Apply additions to itself. - fn apply_additions(&mut self, additions: Self::Additions); + /// Apply changeset to itself. + fn apply_changeset(&mut self, changeset: Self::ChangeSet); /// Determines whether the transaction should be included in the index. fn is_tx_relevant(&self, tx: &Transaction) -> bool; diff --git a/crates/chain/src/keychain.rs b/crates/chain/src/keychain.rs index 7193a79921..f9c625eebf 100644 --- a/crates/chain/src/keychain.rs +++ b/crates/chain/src/keychain.rs @@ -11,8 +11,7 @@ //! [`SpkTxOutIndex`]: crate::SpkTxOutIndex use crate::{ - collections::BTreeMap, indexed_tx_graph::IndexedAdditions, local_chain, tx_graph::TxGraph, - Anchor, Append, + collections::BTreeMap, indexed_tx_graph, local_chain, tx_graph::TxGraph, Anchor, Append, }; #[cfg(feature = "miniscript")] @@ -22,11 +21,11 @@ pub use txout_index::*; /// Represents updates to the derivation index of a [`KeychainTxOutIndex`]. /// -/// It can be applied to [`KeychainTxOutIndex`] with [`apply_additions`]. [`DerivationAdditions] are +/// It can be applied to [`KeychainTxOutIndex`] with [`apply_changeset`]. [`ChangeSet] are /// monotone in that they will never decrease the revealed derivation index. /// /// [`KeychainTxOutIndex`]: crate::keychain::KeychainTxOutIndex -/// [`apply_additions`]: crate::keychain::KeychainTxOutIndex::apply_additions +/// [`apply_changeset`]: crate::keychain::KeychainTxOutIndex::apply_changeset #[derive(Clone, Debug, PartialEq)] #[cfg_attr( feature = "serde", @@ -40,17 +39,17 @@ pub use txout_index::*; ) )] #[must_use] -pub struct DerivationAdditions(pub BTreeMap); +pub struct ChangeSet(pub BTreeMap); -impl DerivationAdditions { +impl ChangeSet { /// Get the inner map of the keychain to its new derivation index. pub fn as_inner(&self) -> &BTreeMap { &self.0 } } -impl Append for DerivationAdditions { - /// Append another [`DerivationAdditions`] into self. +impl Append for ChangeSet { + /// Append another [`ChangeSet`] into self. /// /// If the keychain already exists, increase the index when the other's index > self's index. /// If the keychain did not exist, append the new keychain. @@ -64,19 +63,19 @@ impl Append for DerivationAdditions { self.0.append(&mut other.0); } - /// Returns whether the additions are empty. + /// Returns whether the changeset are empty. fn is_empty(&self) -> bool { self.0.is_empty() } } -impl Default for DerivationAdditions { +impl Default for ChangeSet { fn default() -> Self { Self(Default::default()) } } -impl AsRef> for DerivationAdditions { +impl AsRef> for ChangeSet { fn as_ref(&self) -> &BTreeMap { &self.0 } @@ -102,8 +101,6 @@ pub struct LocalUpdate { impl LocalUpdate { /// Construct a [`LocalUpdate`] with a given [`local_chain::Update`]. - /// - /// [`CheckPoint`]: local_chain::CheckPoint pub fn new(chain_update: local_chain::Update) -> Self { Self { last_active_indices: BTreeMap::new(), @@ -132,17 +129,17 @@ pub struct LocalChangeSet { /// [`LocalChain`]: local_chain::LocalChain pub chain_changeset: local_chain::ChangeSet, - /// Additions to [`IndexedTxGraph`]. + /// ChangeSet to [`IndexedTxGraph`]. /// /// [`IndexedTxGraph`]: crate::indexed_tx_graph::IndexedTxGraph - pub indexed_additions: IndexedAdditions>, + pub indexed_changeset: indexed_tx_graph::ChangeSet>, } impl Default for LocalChangeSet { fn default() -> Self { Self { chain_changeset: Default::default(), - indexed_additions: Default::default(), + indexed_changeset: Default::default(), } } } @@ -150,11 +147,11 @@ impl Default for LocalChangeSet { impl Append for LocalChangeSet { fn append(&mut self, other: Self) { Append::append(&mut self.chain_changeset, other.chain_changeset); - Append::append(&mut self.indexed_additions, other.indexed_additions); + Append::append(&mut self.indexed_changeset, other.indexed_changeset); } fn is_empty(&self) -> bool { - self.chain_changeset.is_empty() && self.indexed_additions.is_empty() + self.chain_changeset.is_empty() && self.indexed_changeset.is_empty() } } @@ -167,10 +164,10 @@ impl From for LocalChangeSet { } } -impl From>> for LocalChangeSet { - fn from(indexed_additions: IndexedAdditions>) -> Self { +impl From>> for LocalChangeSet { + fn from(indexed_changeset: indexed_tx_graph::ChangeSet>) -> Self { Self { - indexed_additions, + indexed_changeset, ..Default::default() } } @@ -254,8 +251,8 @@ mod test { lhs_di.insert(Keychain::Three, 3); rhs_di.insert(Keychain::Four, 4); - let mut lhs = DerivationAdditions(lhs_di); - let rhs = DerivationAdditions(rhs_di); + let mut lhs = ChangeSet(lhs_di); + let rhs = ChangeSet(rhs_di); lhs.append(rhs); // Exiting index doesn't update if the new index in `other` is lower than `self`. diff --git a/crates/chain/src/keychain/txout_index.rs b/crates/chain/src/keychain/txout_index.rs index 2c5d8d1c40..456fb4c0c2 100644 --- a/crates/chain/src/keychain/txout_index.rs +++ b/crates/chain/src/keychain/txout_index.rs @@ -11,8 +11,6 @@ use core::{fmt::Debug, ops::Deref}; use crate::Append; -use super::DerivationAdditions; - /// A convenient wrapper around [`SpkTxOutIndex`] that relates script pubkeys to miniscript public /// [`Descriptor`]s. /// @@ -23,7 +21,7 @@ use super::DerivationAdditions; /// revealed. In addition to revealed scripts, we have a `lookahead` parameter for each keychain, /// which defines the number of script pubkeys to store ahead of the last revealed index. /// -/// Methods that could update the last revealed index will return [`DerivationAdditions`] to report +/// Methods that could update the last revealed index will return [`super::ChangeSet`] to report /// these changes. This can be persisted for future recovery. /// /// ## Synopsis @@ -90,18 +88,18 @@ impl Deref for KeychainTxOutIndex { } impl Indexer for KeychainTxOutIndex { - type Additions = DerivationAdditions; + type ChangeSet = super::ChangeSet; - fn index_txout(&mut self, outpoint: OutPoint, txout: &TxOut) -> Self::Additions { + fn index_txout(&mut self, outpoint: OutPoint, txout: &TxOut) -> Self::ChangeSet { self.scan_txout(outpoint, txout) } - fn index_tx(&mut self, tx: &bitcoin::Transaction) -> Self::Additions { + fn index_tx(&mut self, tx: &bitcoin::Transaction) -> Self::ChangeSet { self.scan(tx) } - fn apply_additions(&mut self, additions: Self::Additions) { - self.apply_additions(additions) + fn apply_changeset(&mut self, changeset: Self::ChangeSet) { + self.apply_changeset(changeset) } fn is_tx_relevant(&self, tx: &bitcoin::Transaction) -> bool { @@ -113,7 +111,7 @@ impl KeychainTxOutIndex { /// Scans an object for relevant outpoints, which are stored and indexed internally. /// /// If the matched script pubkey is part of the lookahead, the last stored index is updated for - /// the script pubkey's keychain and the [`DerivationAdditions`] returned will reflect the + /// the script pubkey's keychain and the [`super::ChangeSet`] returned will reflect the /// change. /// /// Typically, this method is used in two situations: @@ -126,19 +124,19 @@ impl KeychainTxOutIndex { /// See [`ForEachTxout`] for the types that support this. /// /// [`ForEachTxout`]: crate::ForEachTxOut - pub fn scan(&mut self, txouts: &impl ForEachTxOut) -> DerivationAdditions { - let mut additions = DerivationAdditions::::default(); - txouts.for_each_txout(|(op, txout)| additions.append(self.scan_txout(op, txout))); - additions + pub fn scan(&mut self, txouts: &impl ForEachTxOut) -> super::ChangeSet { + let mut changeset = super::ChangeSet::::default(); + txouts.for_each_txout(|(op, txout)| changeset.append(self.scan_txout(op, txout))); + changeset } /// Scan a single outpoint for a matching script pubkey. /// /// If it matches, this will store and index it. - pub fn scan_txout(&mut self, op: OutPoint, txout: &TxOut) -> DerivationAdditions { + pub fn scan_txout(&mut self, op: OutPoint, txout: &TxOut) -> super::ChangeSet { match self.inner.scan_txout(op, txout).cloned() { Some((keychain, index)) => self.reveal_to_target(&keychain, index).1, - None => DerivationAdditions::default(), + None => super::ChangeSet::default(), } } @@ -370,20 +368,20 @@ impl KeychainTxOutIndex { keychains: &BTreeMap, ) -> ( BTreeMap>>, - DerivationAdditions, + super::ChangeSet, ) { - let mut additions = DerivationAdditions::default(); + let mut changeset = super::ChangeSet::default(); let mut spks = BTreeMap::new(); for (keychain, &index) in keychains { - let (new_spks, new_additions) = self.reveal_to_target(keychain, index); - if !new_additions.is_empty() { + let (new_spks, new_changeset) = self.reveal_to_target(keychain, index); + if !new_changeset.is_empty() { spks.insert(keychain.clone(), new_spks); - additions.append(new_additions.clone()); + changeset.append(new_changeset.clone()); } } - (spks, additions) + (spks, changeset) } /// Reveals script pubkeys of the `keychain`'s descriptor **up to and including** the @@ -394,7 +392,7 @@ impl KeychainTxOutIndex { /// reveal up to the last possible index. /// /// This returns an iterator of newly revealed indices (alongside their scripts) and a - /// [`DerivationAdditions`], which reports updates to the latest revealed index. If no new script + /// [`super::ChangeSet`], which reports updates to the latest revealed index. If no new script /// pubkeys are revealed, then both of these will be empty. /// /// # Panics @@ -406,7 +404,7 @@ impl KeychainTxOutIndex { target_index: u32, ) -> ( SpkIterator>, - DerivationAdditions, + super::ChangeSet, ) { let descriptor = self.keychains.get(keychain).expect("keychain must exist"); let has_wildcard = descriptor.has_wildcard(); @@ -450,7 +448,7 @@ impl KeychainTxOutIndex { debug_assert!(_old_index < Some(index)); ( SpkIterator::new_with_range(descriptor.clone(), next_reveal_index..index + 1), - DerivationAdditions(core::iter::once((keychain.clone(), index)).collect()), + super::ChangeSet(core::iter::once((keychain.clone(), index)).collect()), ) } None => ( @@ -458,7 +456,7 @@ impl KeychainTxOutIndex { descriptor.clone(), next_reveal_index..next_reveal_index, ), - DerivationAdditions::default(), + super::ChangeSet::default(), ), } } @@ -466,10 +464,10 @@ impl KeychainTxOutIndex { /// Attempts to reveal the next script pubkey for `keychain`. /// /// Returns the derivation index of the revealed script pubkey, the revealed script pubkey and a - /// [`DerivationAdditions`] which represents changes in the last revealed index (if any). + /// [`super::ChangeSet`] which represents changes in the last revealed index (if any). /// /// When a new script cannot be revealed, we return the last revealed script and an empty - /// [`DerivationAdditions`]. There are two scenarios when a new script pubkey cannot be derived: + /// [`super::ChangeSet`]. There are two scenarios when a new script pubkey cannot be derived: /// /// 1. The descriptor has no wildcard and already has one script revealed. /// 2. The descriptor has already revealed scripts up to the numeric bound. @@ -477,14 +475,14 @@ impl KeychainTxOutIndex { /// # Panics /// /// Panics if the `keychain` does not exist. - pub fn reveal_next_spk(&mut self, keychain: &K) -> ((u32, &Script), DerivationAdditions) { + pub fn reveal_next_spk(&mut self, keychain: &K) -> ((u32, &Script), super::ChangeSet) { let (next_index, _) = self.next_index(keychain); - let additions = self.reveal_to_target(keychain, next_index).1; + let changeset = self.reveal_to_target(keychain, next_index).1; let script = self .inner .spk_at_index(&(keychain.clone(), next_index)) .expect("script must already be stored"); - ((next_index, script), additions) + ((next_index, script), changeset) } /// Gets the next unused script pubkey in the keychain. I.e., the script pubkey with the lowest @@ -499,7 +497,7 @@ impl KeychainTxOutIndex { /// # Panics /// /// Panics if `keychain` has never been added to the index - pub fn next_unused_spk(&mut self, keychain: &K) -> ((u32, &Script), DerivationAdditions) { + pub fn next_unused_spk(&mut self, keychain: &K) -> ((u32, &Script), super::ChangeSet) { let need_new = self.unused_spks_of_keychain(keychain).next().is_none(); // this rather strange branch is needed because of some lifetime issues if need_new { @@ -509,7 +507,7 @@ impl KeychainTxOutIndex { self.unused_spks_of_keychain(keychain) .next() .expect("we already know next exists"), - DerivationAdditions::default(), + super::ChangeSet::default(), ) } } @@ -580,9 +578,9 @@ impl KeychainTxOutIndex { .collect() } - /// Applies the derivation additions to the [`KeychainTxOutIndex`], extending the number of - /// derived scripts per keychain, as specified in the `additions`. - pub fn apply_additions(&mut self, additions: DerivationAdditions) { - let _ = self.reveal_to_target_multi(&additions.0); + /// Applies the derivation changeset to the [`KeychainTxOutIndex`], extending the number of + /// derived scripts per keychain, as specified in the `changeset`. + pub fn apply_changeset(&mut self, changeset: super::ChangeSet) { + let _ = self.reveal_to_target_multi(&changeset.0); } } diff --git a/crates/chain/src/spk_txout_index.rs b/crates/chain/src/spk_txout_index.rs index cf862fb838..e9e5e16a58 100644 --- a/crates/chain/src/spk_txout_index.rs +++ b/crates/chain/src/spk_txout_index.rs @@ -54,19 +54,19 @@ impl Default for SpkTxOutIndex { } impl Indexer for SpkTxOutIndex { - type Additions = (); + type ChangeSet = (); - fn index_txout(&mut self, outpoint: OutPoint, txout: &TxOut) -> Self::Additions { + fn index_txout(&mut self, outpoint: OutPoint, txout: &TxOut) -> Self::ChangeSet { self.scan_txout(outpoint, txout); Default::default() } - fn index_tx(&mut self, tx: &Transaction) -> Self::Additions { + fn index_tx(&mut self, tx: &Transaction) -> Self::ChangeSet { self.scan(tx); Default::default() } - fn apply_additions(&mut self, _additions: Self::Additions) { + fn apply_changeset(&mut self, _changeset: Self::ChangeSet) { // This applies nothing. } diff --git a/crates/chain/src/tx_graph.rs b/crates/chain/src/tx_graph.rs index c78d071be7..9fd64ba7e9 100644 --- a/crates/chain/src/tx_graph.rs +++ b/crates/chain/src/tx_graph.rs @@ -1,17 +1,17 @@ //! Module for structures that store and traverse transactions. //! //! [`TxGraph`] is a monotone structure that inserts transactions and indexes the spends. The -//! [`Additions`] structure reports changes of [`TxGraph`] but can also be applied to a +//! [`ChangeSet`] structure reports changes of [`TxGraph`] but can also be applied to a //! [`TxGraph`] as well. Lastly, [`TxDescendants`] is an [`Iterator`] that traverses descendants of //! a given transaction. //! //! Conflicting transactions are allowed to coexist within a [`TxGraph`]. This is useful for //! identifying and traversing conflicts and descendants of a given transaction. //! -//! # Previewing and applying changes +//! # Applying changes //! -//! Methods that either preview or apply changes to [`TxGraph`] will return [`Additions`]. -//! [`Additions`] can be applied back to a [`TxGraph`] or be used to inform persistent storage +//! Methods that apply changes to [`TxGraph`] will return [`ChangeSet`]. +//! [`ChangeSet`] can be applied back to a [`TxGraph`] or be used to inform persistent storage //! of the changes to [`TxGraph`]. //! //! ``` @@ -20,16 +20,14 @@ //! # use bdk_chain::example_utils::*; //! # use bitcoin::Transaction; //! # let tx_a = tx_from_hex(RAW_TX_1); -//! # let tx_b = tx_from_hex(RAW_TX_2); //! let mut graph: TxGraph = TxGraph::default(); +//! let mut another_graph: TxGraph = TxGraph::default(); //! -//! // preview a transaction insertion (not actually inserted) -//! let additions = graph.insert_tx_preview(tx_a); -//! // apply the insertion -//! graph.apply_additions(additions); +//! // insert a transaction +//! let changeset = graph.insert_tx(tx_a); //! -//! // you can also insert a transaction directly -//! let already_applied_additions = graph.insert_tx(tx_b); +//! // the resulting changeset can be applied to another tx graph +//! another_graph.apply_changeset(changeset); //! ``` //! //! A [`TxGraph`] can also be updated with another [`TxGraph`]. @@ -44,15 +42,12 @@ //! let mut graph: TxGraph = TxGraph::default(); //! let update = TxGraph::new(vec![tx_a, tx_b]); //! -//! // preview additions as the result of the update -//! let additions = graph.determine_additions(&update); -//! // apply the additions -//! graph.apply_additions(additions); +//! // apply the update graph +//! let changeset = graph.apply_update(update.clone()); //! -//! // we can also apply the update graph directly -//! // the additions will be empty as we have already applied the same update above -//! let additions = graph.apply_update(update); -//! assert!(additions.is_empty()); +//! // if we apply it again, the resulting changeset will be empty +//! let changeset = graph.apply_update(update); +//! assert!(changeset.is_empty()); //! ``` use crate::{ @@ -135,9 +130,9 @@ impl Default for TxNodeInternal { #[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] pub struct CanonicalTx<'a, T, A> { /// How the transaction is observed as (confirmed or unconfirmed). - pub observed_as: ChainPosition<&'a A>, + pub chain_position: ChainPosition<&'a A>, /// The transaction node (as part of the graph). - pub node: TxNode<'a, T, A>, + pub tx_node: TxNode<'a, T, A>, } impl TxGraph { @@ -371,15 +366,16 @@ impl TxGraph { new } - /// Returns the resultant [`Additions`] if the given `txout` is inserted at `outpoint`. Does not - /// mutate `self`. + /// Inserts the given [`TxOut`] at [`OutPoint`]. /// /// Inserting floating txouts are useful for determining fee/feerate of transactions we care /// about. /// - /// The [`Additions`] result will be empty if the `outpoint` (or a full transaction containing + /// The [`ChangeSet`] result will be empty if the `outpoint` (or a full transaction containing /// the `outpoint`) already existed in `self`. - pub fn insert_txout_preview(&self, outpoint: OutPoint, txout: TxOut) -> Additions { + /// + /// [`apply_changeset`]: Self::apply_changeset + pub fn insert_txout(&mut self, outpoint: OutPoint, txout: TxOut) -> ChangeSet { let mut update = Self::default(); update.txs.insert( outpoint.txid, @@ -389,100 +385,62 @@ impl TxGraph { 0, ), ); - self.determine_additions(&update) - } - - /// Inserts the given [`TxOut`] at [`OutPoint`]. - /// - /// This is equivalent to calling [`insert_txout_preview`] and [`apply_additions`] in sequence. - /// - /// [`insert_txout_preview`]: Self::insert_txout_preview - /// [`apply_additions`]: Self::apply_additions - pub fn insert_txout(&mut self, outpoint: OutPoint, txout: TxOut) -> Additions { - let additions = self.insert_txout_preview(outpoint, txout); - self.apply_additions(additions.clone()); - additions + let changeset = self.determine_changeset(&update); + self.apply_changeset(changeset.clone()); + changeset } - /// Returns the resultant [`Additions`] if the given transaction is inserted. Does not actually - /// mutate [`Self`]. + /// Inserts the given transaction into [`TxGraph`]. /// - /// The [`Additions`] result will be empty if `tx` already exists in `self`. - pub fn insert_tx_preview(&self, tx: Transaction) -> Additions { + /// The [`ChangeSet`] returned will be empty if `tx` already exists. + pub fn insert_tx(&mut self, tx: Transaction) -> ChangeSet { let mut update = Self::default(); update .txs .insert(tx.txid(), (TxNodeInternal::Whole(tx), BTreeSet::new(), 0)); - self.determine_additions(&update) - } - - /// Inserts the given transaction into [`TxGraph`]. - /// - /// The [`Additions`] returned will be empty if `tx` already exists. - pub fn insert_tx(&mut self, tx: Transaction) -> Additions { - let additions = self.insert_tx_preview(tx); - self.apply_additions(additions.clone()); - additions - } - - /// Returns the resultant [`Additions`] if the `txid` is set in `anchor`. - pub fn insert_anchor_preview(&self, txid: Txid, anchor: A) -> Additions { - let mut update = Self::default(); - update.anchors.insert((anchor, txid)); - self.determine_additions(&update) + let changeset = self.determine_changeset(&update); + self.apply_changeset(changeset.clone()); + changeset } /// Inserts the given `anchor` into [`TxGraph`]. /// - /// This is equivalent to calling [`insert_anchor_preview`] and [`apply_additions`] in sequence. - /// The [`Additions`] returned will be empty if graph already knows that `txid` exists in + /// The [`ChangeSet`] returned will be empty if graph already knows that `txid` exists in /// `anchor`. - /// - /// [`insert_anchor_preview`]: Self::insert_anchor_preview - /// [`apply_additions`]: Self::apply_additions - pub fn insert_anchor(&mut self, txid: Txid, anchor: A) -> Additions { - let additions = self.insert_anchor_preview(txid, anchor); - self.apply_additions(additions.clone()); - additions + pub fn insert_anchor(&mut self, txid: Txid, anchor: A) -> ChangeSet { + let mut update = Self::default(); + update.anchors.insert((anchor, txid)); + let changeset = self.determine_changeset(&update); + self.apply_changeset(changeset.clone()); + changeset } - /// Returns the resultant [`Additions`] if the `txid` is set to `seen_at`. + /// Inserts the given `seen_at` for `txid` into [`TxGraph`]. /// /// Note that [`TxGraph`] only keeps track of the lastest `seen_at`. - pub fn insert_seen_at_preview(&self, txid: Txid, seen_at: u64) -> Additions { + pub fn insert_seen_at(&mut self, txid: Txid, seen_at: u64) -> ChangeSet { let mut update = Self::default(); let (_, _, update_last_seen) = update.txs.entry(txid).or_default(); *update_last_seen = seen_at; - self.determine_additions(&update) - } - - /// Inserts the given `seen_at` into [`TxGraph`]. - /// - /// This is equivalent to calling [`insert_seen_at_preview`] and [`apply_additions`] in - /// sequence. - /// - /// [`insert_seen_at_preview`]: Self::insert_seen_at_preview - /// [`apply_additions`]: Self::apply_additions - pub fn insert_seen_at(&mut self, txid: Txid, seen_at: u64) -> Additions { - let additions = self.insert_seen_at_preview(txid, seen_at); - self.apply_additions(additions.clone()); - additions + let changeset = self.determine_changeset(&update); + self.apply_changeset(changeset.clone()); + changeset } /// Extends this graph with another so that `self` becomes the union of the two sets of /// transactions. /// - /// The returned [`Additions`] is the set difference between `update` and `self` (transactions that + /// The returned [`ChangeSet`] is the set difference between `update` and `self` (transactions that /// exist in `update` but not in `self`). - pub fn apply_update(&mut self, update: TxGraph) -> Additions { - let additions = self.determine_additions(&update); - self.apply_additions(additions.clone()); - additions + pub fn apply_update(&mut self, update: TxGraph) -> ChangeSet { + let changeset = self.determine_changeset(&update); + self.apply_changeset(changeset.clone()); + changeset } - /// Applies [`Additions`] to [`TxGraph`]. - pub fn apply_additions(&mut self, additions: Additions) { - for tx in additions.txs { + /// Applies [`ChangeSet`] to [`TxGraph`]. + pub fn apply_changeset(&mut self, changeset: ChangeSet) { + for tx in changeset.txs { let txid = tx.txid(); tx.input @@ -513,7 +471,7 @@ impl TxGraph { } } - for (outpoint, txout) in additions.txouts { + for (outpoint, txout) in changeset.txouts { let tx_entry = self .txs .entry(outpoint.txid) @@ -528,14 +486,14 @@ impl TxGraph { } } - for (anchor, txid) in additions.anchors { + for (anchor, txid) in changeset.anchors { if self.anchors.insert((anchor.clone(), txid)) { let (_, anchors, _) = self.txs.entry(txid).or_insert_with(Default::default); anchors.insert(anchor); } } - for (txid, new_last_seen) in additions.last_seen { + for (txid, new_last_seen) in changeset.last_seen { let (_, _, last_seen) = self.txs.entry(txid).or_insert_with(Default::default); if new_last_seen > *last_seen { *last_seen = new_last_seen; @@ -543,21 +501,21 @@ impl TxGraph { } } - /// Previews the resultant [`Additions`] when [`Self`] is updated against the `update` graph. + /// Previews the resultant [`ChangeSet`] when [`Self`] is updated against the `update` graph. /// - /// The [`Additions`] would be the set difference between `update` and `self` (transactions that + /// The [`ChangeSet`] would be the set difference between `update` and `self` (transactions that /// exist in `update` but not in `self`). - pub fn determine_additions(&self, update: &TxGraph) -> Additions { - let mut additions = Additions::default(); + pub(crate) fn determine_changeset(&self, update: &TxGraph) -> ChangeSet { + let mut changeset = ChangeSet::default(); for (&txid, (update_tx_node, _, update_last_seen)) in &update.txs { let prev_last_seen: u64 = match (self.txs.get(&txid), update_tx_node) { (None, TxNodeInternal::Whole(update_tx)) => { - additions.txs.insert(update_tx.clone()); + changeset.txs.insert(update_tx.clone()); 0 } (None, TxNodeInternal::Partial(update_txos)) => { - additions.txouts.extend( + changeset.txouts.extend( update_txos .iter() .map(|(&vout, txo)| (OutPoint::new(txid, vout), txo.clone())), @@ -569,14 +527,14 @@ impl TxGraph { Some((TxNodeInternal::Partial(_), _, last_seen)), TxNodeInternal::Whole(update_tx), ) => { - additions.txs.insert(update_tx.clone()); + changeset.txs.insert(update_tx.clone()); *last_seen } ( Some((TxNodeInternal::Partial(txos), _, last_seen)), TxNodeInternal::Partial(update_txos), ) => { - additions.txouts.extend( + changeset.txouts.extend( update_txos .iter() .filter(|(vout, _)| !txos.contains_key(*vout)) @@ -587,13 +545,13 @@ impl TxGraph { }; if *update_last_seen > prev_last_seen { - additions.last_seen.insert(txid, *update_last_seen); + changeset.last_seen.insert(txid, *update_last_seen); } } - additions.anchors = update.anchors.difference(&self.anchors).cloned().collect(); + changeset.anchors = update.anchors.difference(&self.anchors).cloned().collect(); - additions + changeset } } @@ -804,8 +762,8 @@ impl TxGraph { self.try_get_chain_position(chain, chain_tip, tx.txid) .map(|v| { v.map(|observed_in| CanonicalTx { - observed_as: observed_in, - node: tx, + chain_position: observed_in, + tx_node: tx, }) }) .transpose() @@ -1026,7 +984,7 @@ impl TxGraph { /// A structure that represents changes to a [`TxGraph`]. /// -/// It is named "additions" because [`TxGraph`] is monotone, so transactions can only be added and +/// It is named "changeset" because [`TxGraph`] is monotone, so transactions can only be added and /// not removed. /// /// Refer to [module-level documentation] for more. @@ -1045,7 +1003,7 @@ impl TxGraph { ) )] #[must_use] -pub struct Additions { +pub struct ChangeSet { /// Added transactions. pub txs: BTreeSet, /// Added txouts. @@ -1056,7 +1014,7 @@ pub struct Additions { pub last_seen: BTreeMap, } -impl Default for Additions { +impl Default for ChangeSet { fn default() -> Self { Self { txs: Default::default(), @@ -1067,13 +1025,13 @@ impl Default for Additions { } } -impl Additions { - /// Returns true if the [`Additions`] is empty (no transactions or txouts). +impl ChangeSet { + /// Returns true if the [`ChangeSet`] is empty (no transactions or txouts). pub fn is_empty(&self) -> bool { self.txs.is_empty() && self.txouts.is_empty() } - /// Iterates over all outpoints contained within [`Additions`]. + /// Iterates over all outpoints contained within [`ChangeSet`]. pub fn txouts(&self) -> impl Iterator { self.txs .iter() @@ -1087,7 +1045,7 @@ impl Additions { } } -impl Append for Additions { +impl Append for ChangeSet { fn append(&mut self, mut other: Self) { self.txs.append(&mut other.txs); self.txouts.append(&mut other.txouts); @@ -1117,7 +1075,7 @@ impl AsRef> for TxGraph { } } -impl ForEachTxOut for Additions { +impl ForEachTxOut for ChangeSet { fn for_each_txout(&self, f: impl FnMut((OutPoint, &TxOut))) { self.txouts().for_each(f) } diff --git a/crates/chain/tests/test_indexed_tx_graph.rs b/crates/chain/tests/test_indexed_tx_graph.rs index 59032e65db..fe8505960f 100644 --- a/crates/chain/tests/test_indexed_tx_graph.rs +++ b/crates/chain/tests/test_indexed_tx_graph.rs @@ -4,11 +4,10 @@ mod common; use std::collections::{BTreeMap, BTreeSet}; use bdk_chain::{ - indexed_tx_graph::{IndexedAdditions, IndexedTxGraph}, - keychain::{Balance, DerivationAdditions, KeychainTxOutIndex}, + indexed_tx_graph::{self, IndexedTxGraph}, + keychain::{self, Balance, KeychainTxOutIndex}, local_chain::LocalChain, - tx_graph::Additions, - BlockId, ChainPosition, ConfirmationHeightAnchor, + tx_graph, BlockId, ChainPosition, ConfirmationHeightAnchor, }; use bitcoin::{ secp256k1::Secp256k1, BlockHash, OutPoint, Script, ScriptBuf, Transaction, TxIn, TxOut, @@ -68,12 +67,12 @@ fn insert_relevant_txs() { assert_eq!( graph.insert_relevant_txs(txs.iter().map(|tx| (tx, None)), None), - IndexedAdditions { - graph_additions: Additions { + indexed_tx_graph::ChangeSet { + graph_changeset: tx_graph::ChangeSet { txs: txs.into(), ..Default::default() }, - index_additions: DerivationAdditions([((), 9_u32)].into()), + index_changeset: keychain::ChangeSet([((), 9_u32)].into()), } ) } diff --git a/crates/chain/tests/test_keychain_txout_index.rs b/crates/chain/tests/test_keychain_txout_index.rs index d6c66c3539..937dd6e789 100644 --- a/crates/chain/tests/test_keychain_txout_index.rs +++ b/crates/chain/tests/test_keychain_txout_index.rs @@ -4,7 +4,7 @@ mod common; use bdk_chain::{ collections::BTreeMap, - keychain::{DerivationAdditions, KeychainTxOutIndex}, + keychain::{self, KeychainTxOutIndex}, Append, }; @@ -53,7 +53,7 @@ fn test_set_all_derivation_indices() { assert_eq!(txout_index.last_revealed_indices(), &derive_to); assert_eq!( txout_index.reveal_to_target_multi(&derive_to).1, - DerivationAdditions::default(), + keychain::ChangeSet::default(), "no changes if we set to the same thing" ); } @@ -79,14 +79,14 @@ fn test_lookahead() { // - scripts cached in spk_txout_index should increase correctly // - stored scripts of external keychain should be of expected counts for index in (0..20).skip_while(|i| i % 2 == 1) { - let (revealed_spks, revealed_additions) = + let (revealed_spks, revealed_changeset) = txout_index.reveal_to_target(&TestKeychain::External, index); assert_eq!( revealed_spks.collect::>(), vec![(index, spk_at_index(&external_desc, index))], ); assert_eq!( - revealed_additions.as_inner(), + revealed_changeset.as_inner(), &[(TestKeychain::External, index)].into() ); @@ -129,7 +129,7 @@ fn test_lookahead() { // - derivation index is set ahead of current derivation index + lookahead // expect: // - scripts cached in spk_txout_index should increase correctly, a.k.a. no scripts are skipped - let (revealed_spks, revealed_additions) = + let (revealed_spks, revealed_changeset) = txout_index.reveal_to_target(&TestKeychain::Internal, 24); assert_eq!( revealed_spks.collect::>(), @@ -138,7 +138,7 @@ fn test_lookahead() { .collect::>(), ); assert_eq!( - revealed_additions.as_inner(), + revealed_changeset.as_inner(), &[(TestKeychain::Internal, 24)].into() ); assert_eq!( @@ -191,7 +191,7 @@ fn test_lookahead() { ], ..common::new_tx(external_index) }; - assert_eq!(txout_index.scan(&tx), DerivationAdditions::default()); + assert_eq!(txout_index.scan(&tx), keychain::ChangeSet::default()); assert_eq!( txout_index.last_revealed_index(&TestKeychain::External), Some(last_external_index) @@ -245,9 +245,9 @@ fn test_scan_with_lookahead() { value: 0, }; - let additions = txout_index.scan_txout(op, &txout); + let changeset = txout_index.scan_txout(op, &txout); assert_eq!( - additions.as_inner(), + changeset.as_inner(), &[(TestKeychain::External, spk_i)].into() ); assert_eq!( @@ -270,8 +270,8 @@ fn test_scan_with_lookahead() { script_pubkey: spk_41, value: 0, }; - let additions = txout_index.scan_txout(op, &txout); - assert!(additions.is_empty()); + let changeset = txout_index.scan_txout(op, &txout); + assert!(changeset.is_empty()); } #[test] @@ -287,8 +287,8 @@ fn test_wildcard_derivations() { // - unused list is also empty // // - next_derivation_index() == (0, true) - // - derive_new() == ((0, ), DerivationAdditions) - // - next_unused() == ((0, ), DerivationAdditions:is_empty()) + // - derive_new() == ((0, ), keychain::ChangeSet) + // - next_unused() == ((0, ), keychain::ChangeSet:is_empty()) assert_eq!(txout_index.next_index(&TestKeychain::External), (0, true)); let (spk, changeset) = txout_index.reveal_next_spk(&TestKeychain::External); assert_eq!(spk, (0_u32, external_spk_0.as_script())); @@ -303,8 +303,8 @@ fn test_wildcard_derivations() { // - unused list: [16, 18, 19, 21, 22, 24, 25] // - next_derivation_index() = (26, true) - // - derive_new() = ((26, ), DerivationAdditions) - // - next_unused() == ((16, ), DerivationAdditions::is_empty()) + // - derive_new() = ((26, ), keychain::ChangeSet) + // - next_unused() == ((16, ), keychain::ChangeSet::is_empty()) let _ = txout_index.reveal_to_target(&TestKeychain::External, 25); (0..=15) @@ -323,7 +323,7 @@ fn test_wildcard_derivations() { assert_eq!(changeset.as_inner(), &[].into()); // - Use all the derived till 26. - // - next_unused() = ((27, ), DerivationAdditions) + // - next_unused() = ((27, ), keychain::ChangeSet) (0..=26).for_each(|index| { txout_index.mark_used(&TestKeychain::External, index); }); @@ -366,7 +366,7 @@ fn test_non_wildcard_derivations() { // expect: // - next derivation index should not be new // - derive new and next unused should return the old script - // - store_up_to should not panic and return empty additions + // - store_up_to should not panic and return empty changeset assert_eq!(txout_index.next_index(&TestKeychain::External), (0, false)); txout_index.mark_used(&TestKeychain::External, 0); @@ -377,8 +377,8 @@ fn test_non_wildcard_derivations() { let (spk, changeset) = txout_index.next_unused_spk(&TestKeychain::External); assert_eq!(spk, (0, external_spk.as_script())); assert_eq!(changeset.as_inner(), &[].into()); - let (revealed_spks, revealed_additions) = + let (revealed_spks, revealed_changeset) = txout_index.reveal_to_target(&TestKeychain::External, 200); assert_eq!(revealed_spks.count(), 0); - assert!(revealed_additions.is_empty()); + assert!(revealed_changeset.is_empty()); } diff --git a/crates/chain/tests/test_tx_graph.rs b/crates/chain/tests/test_tx_graph.rs index 1a05844fe7..9cd58f9798 100644 --- a/crates/chain/tests/test_tx_graph.rs +++ b/crates/chain/tests/test_tx_graph.rs @@ -3,7 +3,7 @@ mod common; use bdk_chain::{ collections::*, local_chain::LocalChain, - tx_graph::{Additions, TxGraph}, + tx_graph::{ChangeSet, TxGraph}, Anchor, Append, BlockId, ChainPosition, ConfirmationHeightAnchor, }; use bitcoin::{ @@ -70,7 +70,7 @@ fn insert_txouts() { for (outpoint, txout) in &original_ops { assert_eq!( graph.insert_txout(*outpoint, txout.clone()), - Additions { + ChangeSet { txouts: [(*outpoint, txout.clone())].into(), ..Default::default() } @@ -86,7 +86,7 @@ fn insert_txouts() { // Insert partials transactions assert_eq!( graph.insert_txout(*outpoint, txout.clone()), - Additions { + ChangeSet { txouts: [(*outpoint, txout.clone())].into(), ..Default::default() } @@ -94,7 +94,7 @@ fn insert_txouts() { // Mark them unconfirmed. assert_eq!( graph.insert_anchor(outpoint.txid, unconf_anchor), - Additions { + ChangeSet { txs: [].into(), txouts: [].into(), anchors: [(unconf_anchor, outpoint.txid)].into(), @@ -104,7 +104,7 @@ fn insert_txouts() { // Mark them last seen at. assert_eq!( graph.insert_seen_at(outpoint.txid, 1000000), - Additions { + ChangeSet { txs: [].into(), txouts: [].into(), anchors: [].into(), @@ -115,7 +115,7 @@ fn insert_txouts() { // Insert the full transaction assert_eq!( graph.insert_tx(update_txs.clone()), - Additions { + ChangeSet { txs: [update_txs.clone()].into(), ..Default::default() } @@ -124,7 +124,7 @@ fn insert_txouts() { // Mark it as confirmed. assert_eq!( graph.insert_anchor(update_txs.txid(), conf_anchor), - Additions { + ChangeSet { txs: [].into(), txouts: [].into(), anchors: [(conf_anchor, update_txs.txid())].into(), @@ -135,11 +135,11 @@ fn insert_txouts() { }; // Check the resulting addition. - let additions = graph.determine_additions(&update); + let changeset = graph.apply_update(update); assert_eq!( - additions, - Additions { + changeset, + ChangeSet { txs: [update_txs.clone()].into(), txouts: update_ops.into(), anchors: [(conf_anchor, update_txs.txid()), (unconf_anchor, h!("tx2"))].into(), @@ -147,8 +147,8 @@ fn insert_txouts() { } ); - // Apply addition and check the new graph counts. - graph.apply_additions(additions); + // Check the new graph counts. + graph.apply_changeset(changeset); assert_eq!(graph.all_txouts().count(), 4); assert_eq!(graph.full_txs().count(), 1); assert_eq!(graph.floating_txouts().count(), 3); @@ -299,7 +299,7 @@ fn insert_tx_displaces_txouts() { }, ); - let _additions = tx_graph.insert_tx(tx.clone()); + let _changeset = tx_graph.insert_tx(tx.clone()); assert_eq!( tx_graph @@ -333,7 +333,7 @@ fn insert_txout_does_not_displace_tx() { }], }; - let _additions = tx_graph.insert_tx(tx.clone()); + let _changeset = tx_graph.insert_tx(tx.clone()); let _ = tx_graph.insert_txout( OutPoint { @@ -794,7 +794,7 @@ fn test_chain_spends() { /// Ensure that `last_seen` values only increase during [`Append::append`]. #[test] -fn test_additions_last_seen_append() { +fn test_changeset_last_seen_append() { let txid: Txid = h!("test txid"); let test_cases: &[(Option, Option)] = &[ @@ -806,11 +806,11 @@ fn test_additions_last_seen_append() { ]; for (original_ls, update_ls) in test_cases { - let mut original = Additions::<()> { + let mut original = ChangeSet::<()> { last_seen: original_ls.map(|ls| (txid, ls)).into_iter().collect(), ..Default::default() }; - let update = Additions::<()> { + let update = ChangeSet::<()> { last_seen: update_ls.map(|ls| (txid, ls)).into_iter().collect(), ..Default::default() }; diff --git a/crates/electrum/src/electrum_ext.rs b/crates/electrum/src/electrum_ext.rs index cf7009df57..985fd06693 100644 --- a/crates/electrum/src/electrum_ext.rs +++ b/crates/electrum/src/electrum_ext.rs @@ -117,13 +117,13 @@ impl ElectrumUpdate { ) .collect::>(); - let graph_additions = { - let old_additions = TxGraph::default().determine_additions(&update.graph); - tx_graph::Additions { - txs: old_additions.txs, - txouts: old_additions.txouts, - last_seen: old_additions.last_seen, - anchors: old_additions + let graph_changeset = { + let old_changeset = TxGraph::default().apply_update(update.graph.clone()); + tx_graph::ChangeSet { + txs: old_changeset.txs, + txouts: old_changeset.txouts, + last_seen: old_changeset.last_seen, + anchors: old_changeset .anchors .into_iter() .map(|(height_anchor, txid)| { @@ -144,7 +144,7 @@ impl ElectrumUpdate { last_active_indices: update.last_active_indices, graph: { let mut graph = TxGraph::default(); - graph.apply_additions(graph_additions); + graph.apply_changeset(graph_changeset); graph }, chain: update.chain, diff --git a/example-crates/example_cli/src/lib.rs b/example-crates/example_cli/src/lib.rs index 513f74b8c2..18bed2c93b 100644 --- a/example-crates/example_cli/src/lib.rs +++ b/example-crates/example_cli/src/lib.rs @@ -10,8 +10,8 @@ use bdk_chain::{ absolute, address, psbt::Prevouts, secp256k1::Secp256k1, sighash::SighashCache, Address, Network, Sequence, Transaction, TxIn, TxOut, }, - indexed_tx_graph::{IndexedAdditions, IndexedTxGraph}, - keychain::{DerivationAdditions, KeychainTxOutIndex}, + indexed_tx_graph::{self, IndexedTxGraph}, + keychain::{self, KeychainTxOutIndex}, miniscript::{ descriptor::{DescriptorSecretKey, KeyMap}, Descriptor, DescriptorPublicKey, @@ -24,7 +24,7 @@ pub use clap; use clap::{Parser, Subcommand}; pub type KeychainTxGraph = IndexedTxGraph>; -pub type KeychainAdditions = IndexedAdditions>; +pub type KeychainChangeSet = indexed_tx_graph::ChangeSet>; pub type Database<'m, C> = Persist, C>; #[derive(Parser)] @@ -186,7 +186,7 @@ pub fn run_address_cmd( cmd: AddressCmd, ) -> anyhow::Result<()> where - C: Default + Append + DeserializeOwned + Serialize + From>, + C: Default + Append + DeserializeOwned + Serialize + From>, { let index = &mut graph.index; @@ -198,9 +198,9 @@ where _ => unreachable!("only these two variants exist in match arm"), }; - let ((spk_i, spk), index_additions) = spk_chooser(index, &Keychain::External); + let ((spk_i, spk), index_changeset) = spk_chooser(index, &Keychain::External); let db = &mut *db.lock().unwrap(); - db.stage(C::from(KeychainAdditions::from(index_additions))); + db.stage(C::from(KeychainChangeSet::from(index_changeset))); db.commit()?; let addr = Address::from_script(spk, network).context("failed to derive address")?; println!("[address @ {}] {}", spk_i, addr); @@ -340,20 +340,20 @@ pub fn run_send_cmd( ) -> anyhow::Result<()> where O::Error: std::error::Error + Send + Sync + 'static, - C: Default + Append + DeserializeOwned + Serialize + From>, + C: Default + Append + DeserializeOwned + Serialize + From>, { let (transaction, change_index) = { let graph = &mut *graph.lock().unwrap(); // take mutable ref to construct tx -- it is only open for a short time while building it. let (tx, change_info) = create_tx(graph, chain, keymap, cs_algorithm, address, value)?; - if let Some((index_additions, (change_keychain, index))) = change_info { + if let Some((index_changeset, (change_keychain, index))) = change_info { // We must first persist to disk the fact that we've got a new address from the // change keychain so future scans will find the tx we're about to broadcast. // If we're unable to persist this, then we don't want to broadcast. { let db = &mut *db.lock().unwrap(); - db.stage(C::from(KeychainAdditions::from(index_additions))); + db.stage(C::from(KeychainChangeSet::from(index_changeset))); db.commit()?; } @@ -371,12 +371,12 @@ where Ok(_) => { println!("Broadcasted Tx : {}", transaction.txid()); - let keychain_additions = graph.lock().unwrap().insert_tx(&transaction, None, None); + let keychain_changeset = graph.lock().unwrap().insert_tx(&transaction, None, None); // We know the tx is at least unconfirmed now. Note if persisting here fails, // it's not a big deal since we can always find it again form // blockchain. - db.lock().unwrap().stage(C::from(keychain_additions)); + db.lock().unwrap().stage(C::from(keychain_changeset)); Ok(()) } Err(e) => { @@ -399,12 +399,12 @@ pub fn create_tx( value: u64, ) -> anyhow::Result<( Transaction, - Option<(DerivationAdditions, (Keychain, u32))>, + Option<(keychain::ChangeSet, (Keychain, u32))>, )> where O::Error: std::error::Error + Send + Sync + 'static, { - let mut additions = DerivationAdditions::default(); + let mut changeset = keychain::ChangeSet::default(); let assets = bdk_tmp_plan::Assets { keys: keymap.iter().map(|(pk, _)| pk.clone()).collect(), @@ -452,9 +452,9 @@ where Keychain::External }; - let ((change_index, change_script), change_additions) = + let ((change_index, change_script), change_changeset) = graph.index.next_unused_spk(&internal_keychain); - additions.append(change_additions); + changeset.append(change_changeset); // Clone to drop the immutable reference. let change_script = change_script.into(); @@ -594,7 +594,7 @@ where } let change_info = if selection_meta.drain_value.is_some() { - Some((additions, (internal_keychain, change_index))) + Some((changeset, (internal_keychain, change_index))) } else { None }; @@ -645,7 +645,7 @@ pub fn handle_commands( ) -> anyhow::Result<()> where O::Error: std::error::Error + Send + Sync + 'static, - C: Default + Append + DeserializeOwned + Serialize + From>, + C: Default + Append + DeserializeOwned + Serialize + From>, { match cmd { Commands::ChainSpecific(_) => unreachable!("example code should handle this!"), diff --git a/example-crates/example_electrum/src/main.rs b/example-crates/example_electrum/src/main.rs index 8e15998e68..39548f756e 100644 --- a/example-crates/example_electrum/src/main.rs +++ b/example-crates/example_electrum/src/main.rs @@ -6,7 +6,7 @@ use std::{ use bdk_chain::{ bitcoin::{Address, Network, OutPoint, ScriptBuf, Txid}, - indexed_tx_graph::{IndexedAdditions, IndexedTxGraph}, + indexed_tx_graph::{self, IndexedTxGraph}, keychain::LocalChangeSet, local_chain::LocalChain, Append, ConfirmationHeightAnchor, @@ -68,7 +68,7 @@ fn main() -> anyhow::Result<()> { let graph = Mutex::new({ let mut graph = IndexedTxGraph::new(index); - graph.apply_additions(init_changeset.indexed_additions); + graph.apply_changeset(init_changeset.indexed_changeset); graph }); @@ -234,8 +234,8 @@ fn main() -> anyhow::Result<()> { let unconfirmed_txids = graph .graph() .list_chain_txs(&*chain, chain_tip) - .filter(|canonical_tx| !canonical_tx.observed_as.is_confirmed()) - .map(|canonical_tx| canonical_tx.node.txid) + .filter(|canonical_tx| !canonical_tx.chain_position.is_confirmed()) + .map(|canonical_tx| canonical_tx.tx_node.txid) .collect::>(); txids = Box::new(unconfirmed_txids.into_iter().inspect(|txid| { @@ -277,21 +277,22 @@ fn main() -> anyhow::Result<()> { let chain_changeset = chain.apply_update(final_update.chain)?; - let indexed_additions = { - let mut additions = IndexedAdditions::::default(); - let (_, index_additions) = graph + let indexed_changeset = { + let mut changeset = + indexed_tx_graph::ChangeSet::::default(); + let (_, index_changeset) = graph .index .reveal_to_target_multi(&final_update.last_active_indices); - additions.append(IndexedAdditions { - index_additions, + changeset.append(indexed_tx_graph::ChangeSet { + index_changeset, ..Default::default() }); - additions.append(graph.apply_update(final_update.graph)); - additions + changeset.append(graph.apply_update(final_update.graph)); + changeset }; ChangeSet { - indexed_additions, + indexed_changeset, chain_changeset, } };