From 0505cd72424a621825f8312af2e342b13a1fc65d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BF=97=E5=AE=87?= Date: Wed, 8 Mar 2023 11:39:25 +1300 Subject: [PATCH] Remove transaction-based type parameters and traits --- crates/bdk/src/wallet/mod.rs | 9 +- crates/chain/src/chain_graph.rs | 111 +++++++++----------- crates/chain/src/keychain.rs | 46 ++++---- crates/chain/src/keychain/tracker.rs | 45 ++++---- crates/chain/src/sparse_chain.rs | 14 +-- crates/chain/src/tx_data_traits.rs | 88 +--------------- crates/chain/src/tx_graph.rs | 140 +++++++++---------------- crates/chain/tests/test_chain_graph.rs | 6 +- crates/chain/tests/test_tx_graph.rs | 6 +- crates/electrum/src/lib.rs | 16 ++- crates/file_store/src/file_store.rs | 32 +++--- crates/file_store/src/lib.rs | 3 +- 12 files changed, 180 insertions(+), 336 deletions(-) diff --git a/crates/bdk/src/wallet/mod.rs b/crates/bdk/src/wallet/mod.rs index 340705a5..41a57919 100644 --- a/crates/bdk/src/wallet/mod.rs +++ b/crates/bdk/src/wallet/mod.rs @@ -23,7 +23,7 @@ pub use bdk_chain::keychain::Balance; use bdk_chain::{ chain_graph, keychain::{persist, KeychainChangeSet, KeychainScan, KeychainTracker}, - sparse_chain, BlockId, ConfirmationTime, IntoOwned, + sparse_chain, BlockId, ConfirmationTime, }; use bitcoin::consensus::encode::serialize; use bitcoin::secp256k1::Secp256k1; @@ -91,11 +91,11 @@ pub struct Wallet { /// The update to a [`Wallet`] used in [`Wallet::apply_update`]. This is usually returned from blockchain data sources. /// The type parameter `T` indicates the kind of transaction contained in the update. It's usually a [`bitcoin::Transaction`]. -pub type Update = KeychainScan; +pub type Update = KeychainScan; /// Error indicating that something was wrong with an [`Update`]. pub type UpdateError = chain_graph::UpdateError; /// The changeset produced internally by applying an update -pub(crate) type ChangeSet = KeychainChangeSet; +pub(crate) type ChangeSet = KeychainChangeSet; /// The address index selection strategy to use to derived an address from the wallet's external /// descriptor. See [`Wallet::get_address`]. If you're unsure which one to use use `WalletIndex::New`. @@ -1686,10 +1686,9 @@ impl Wallet { /// transactions related to your wallet into it. /// /// [`commit`]: Self::commit - pub fn apply_update(&mut self, update: Update) -> Result<(), UpdateError> + pub fn apply_update(&mut self, update: Update) -> Result<(), UpdateError> where D: persist::PersistBackend, - Tx: IntoOwned + Clone, { let changeset = self.keychain_tracker.apply_update(update)?; self.persist.stage(changeset); diff --git a/crates/chain/src/chain_graph.rs b/crates/chain/src/chain_graph.rs index a446ed20..8d1eda66 100644 --- a/crates/chain/src/chain_graph.rs +++ b/crates/chain/src/chain_graph.rs @@ -3,7 +3,7 @@ use crate::{ collections::HashSet, sparse_chain::{self, ChainPosition, SparseChain}, tx_graph::{self, TxGraph}, - AsTransaction, BlockId, ForEachTxOut, FullTxOut, IntoOwned, TxHeight, + BlockId, ForEachTxOut, FullTxOut, TxHeight, }; use alloc::{string::ToString, vec::Vec}; use bitcoin::{OutPoint, Transaction, TxOut, Txid}; @@ -25,12 +25,12 @@ use core::fmt::Debug; /// `graph` but not the other way around. Transactions may fall out of the *chain* (via re-org or /// mempool eviction) but will remain in the *graph*. #[derive(Clone, Debug, PartialEq)] -pub struct ChainGraph

{ +pub struct ChainGraph

{ chain: SparseChain

, - graph: TxGraph, + graph: TxGraph, } -impl Default for ChainGraph { +impl

Default for ChainGraph

{ fn default() -> Self { Self { chain: Default::default(), @@ -39,40 +39,39 @@ impl Default for ChainGraph { } } -impl AsRef> for ChainGraph { +impl

AsRef> for ChainGraph

{ fn as_ref(&self) -> &SparseChain

{ &self.chain } } -impl AsRef> for ChainGraph { - fn as_ref(&self) -> &TxGraph { +impl

AsRef for ChainGraph

{ + fn as_ref(&self) -> &TxGraph { &self.graph } } -impl AsRef> for ChainGraph { - fn as_ref(&self) -> &ChainGraph { +impl

AsRef> for ChainGraph

{ + fn as_ref(&self) -> &ChainGraph

{ self } } -impl ChainGraph { +impl

ChainGraph

{ /// Returns a reference to the internal [`SparseChain`]. pub fn chain(&self) -> &SparseChain

{ &self.chain } /// Returns a reference to the internal [`TxGraph`]. - pub fn graph(&self) -> &TxGraph { + pub fn graph(&self) -> &TxGraph { &self.graph } } -impl ChainGraph +impl

ChainGraph

where P: ChainPosition, - T: AsTransaction + Clone + Ord, { /// Create a new chain graph from a `chain` and a `graph`. /// @@ -82,14 +81,12 @@ where /// transaction in `graph`. /// 2. The `chain` has two transactions that allegedly in it but they conflict in the `graph` /// (so could not possibly be in the same chain). - pub fn new(chain: SparseChain

, graph: TxGraph) -> Result> { + pub fn new(chain: SparseChain

, graph: TxGraph) -> Result> { let mut missing = HashSet::default(); for (pos, txid) in chain.txids() { if let Some(tx) = graph.get_tx(*txid) { let conflict = graph - .walk_conflicts(tx.as_tx(), |_, txid| { - Some((chain.tx_position(txid)?.clone(), txid)) - }) + .walk_conflicts(tx, |_, txid| Some((chain.tx_position(txid)?.clone(), txid))) .next(); if let Some((conflict_pos, conflict)) = conflict { return Err(NewError::Conflict { @@ -128,8 +125,8 @@ where pub fn inflate_update( &self, update: SparseChain

, - new_txs: impl IntoIterator, - ) -> Result, NewError

> { + new_txs: impl IntoIterator, + ) -> Result, NewError

> { let mut inflated_chain = SparseChain::default(); let mut inflated_graph = TxGraph::default(); @@ -188,7 +185,7 @@ where /// Determines the changes required to invalidate checkpoints `from_height` (inclusive) and /// above. Displaced transactions will have their positions moved to [`TxHeight::Unconfirmed`]. - pub fn invalidate_checkpoints_preview(&self, from_height: u32) -> ChangeSet { + pub fn invalidate_checkpoints_preview(&self, from_height: u32) -> ChangeSet

{ ChangeSet { chain: self.chain.invalidate_checkpoints_preview(from_height), ..Default::default() @@ -200,9 +197,9 @@ where /// /// This is equivalent to calling [`Self::invalidate_checkpoints_preview`] and /// [`Self::apply_changeset`] in sequence. - pub fn invalidate_checkpoints(&mut self, from_height: u32) -> ChangeSet + pub fn invalidate_checkpoints(&mut self, from_height: u32) -> ChangeSet

where - ChangeSet: Clone, + ChangeSet

: Clone, { let changeset = self.invalidate_checkpoints_preview(from_height); self.apply_changeset(changeset.clone()); @@ -213,7 +210,7 @@ where /// /// This does not necessarily mean that it is *confirmed* in the blockchain, it might just be in /// the unconfirmed transaction list within the [`SparseChain`]. - pub fn get_tx_in_chain(&self, txid: Txid) -> Option<(&P, &T)> { + pub fn get_tx_in_chain(&self, txid: Txid) -> Option<(&P, &Transaction)> { let position = self.chain.tx_position(txid)?; let full_tx = self.graph.get_tx(txid).expect("must exist"); Some((position, full_tx)) @@ -224,9 +221,13 @@ where /// /// If inserting it into the chain `position` will result in conflicts, the returned /// [`ChangeSet`] should evict conflicting transactions. - pub fn insert_tx_preview(&self, tx: T, pos: P) -> Result, InsertTxError

> { + pub fn insert_tx_preview( + &self, + tx: Transaction, + pos: P, + ) -> Result, InsertTxError

> { let mut changeset = ChangeSet { - chain: self.chain.insert_tx_preview(tx.as_tx().txid(), pos)?, + chain: self.chain.insert_tx_preview(tx.txid(), pos)?, graph: self.graph.insert_tx_preview(tx), }; self.fix_conflicts(&mut changeset)?; @@ -237,14 +238,14 @@ where /// /// This is equivalent to calling [`Self::insert_tx_preview`] and [`Self::apply_changeset`] in /// sequence. - pub fn insert_tx(&mut self, tx: T, pos: P) -> Result, InsertTxError

> { + pub fn insert_tx(&mut self, tx: Transaction, pos: P) -> Result, InsertTxError

> { let changeset = self.insert_tx_preview(tx, pos)?; self.apply_changeset(changeset.clone()); Ok(changeset) } /// Determines the changes required to insert a [`TxOut`] into the internal [`TxGraph`]. - pub fn insert_txout_preview(&self, outpoint: OutPoint, txout: TxOut) -> ChangeSet { + pub fn insert_txout_preview(&self, outpoint: OutPoint, txout: TxOut) -> ChangeSet

{ ChangeSet { chain: Default::default(), graph: self.graph.insert_txout_preview(outpoint, txout), @@ -255,7 +256,7 @@ where /// /// This is equivalent to calling [`Self::insert_txout_preview`] and [`Self::apply_changeset`] /// in sequence. - pub fn insert_txout(&mut self, outpoint: OutPoint, txout: TxOut) -> ChangeSet { + pub fn insert_txout(&mut self, outpoint: OutPoint, txout: TxOut) -> ChangeSet

{ let changeset = self.insert_txout_preview(outpoint, txout); self.apply_changeset(changeset.clone()); changeset @@ -269,7 +270,7 @@ where pub fn insert_checkpoint_preview( &self, block_id: BlockId, - ) -> Result, InsertCheckpointError> { + ) -> Result, InsertCheckpointError> { self.chain .insert_checkpoint_preview(block_id) .map(|chain_changeset| ChangeSet { @@ -285,20 +286,17 @@ where pub fn insert_checkpoint( &mut self, block_id: BlockId, - ) -> Result, InsertCheckpointError> { + ) -> Result, InsertCheckpointError> { let changeset = self.insert_checkpoint_preview(block_id)?; self.apply_changeset(changeset.clone()); Ok(changeset) } /// Calculates the difference between self and `update` in the form of a [`ChangeSet`]. - pub fn determine_changeset( + pub fn determine_changeset( &self, - update: &ChainGraph, - ) -> Result, UpdateError

> - where - T2: IntoOwned + Clone, - { + update: &ChainGraph

, + ) -> Result, UpdateError

> { let chain_changeset = self .chain .determine_changeset(&update.chain) @@ -333,10 +331,7 @@ where /// /// **WARNING:** If there are any missing full txs, conflict resolution will not be complete. In /// debug mode, this will result in panic. - fn fix_conflicts( - &self, - changeset: &mut ChangeSet, - ) -> Result<(), UnresolvableConflict

> { + fn fix_conflicts(&self, changeset: &mut ChangeSet

) -> Result<(), UnresolvableConflict

> { let mut chain_conflicts = vec![]; for (&txid, pos_change) in &changeset.chain.txids { @@ -355,11 +350,7 @@ where let mut full_tx = self.graph.get_tx(txid); if full_tx.is_none() { - full_tx = changeset - .graph - .tx - .iter() - .find(|tx| tx.as_tx().txid() == txid) + full_tx = changeset.graph.tx.iter().find(|tx| tx.txid() == txid) } debug_assert!(full_tx.is_some(), "should have full tx at this point"); @@ -369,7 +360,7 @@ where None => continue, }; - for (conflict_pos, conflict_txid) in self.tx_conflicts_in_chain(full_tx.as_tx()) { + for (conflict_pos, conflict_txid) in self.tx_conflicts_in_chain(full_tx) { chain_conflicts.push((pos.clone(), txid, conflict_pos, conflict_txid)) } } @@ -416,17 +407,14 @@ where /// /// **Warning** this method assumes the changeset is assumed to be correctly formed. If it isn't /// then the chain graph may not behave correctly in the future and may panic unexpectedly. - pub fn apply_changeset(&mut self, changeset: ChangeSet) { + pub fn apply_changeset(&mut self, changeset: ChangeSet

) { self.chain.apply_changeset(changeset.chain); self.graph.apply_additions(changeset.graph); } /// Applies the `update` chain graph. Note this is shorthand for calling /// [`Self::determine_changeset()`] and [`Self::apply_changeset()`] in sequence. - pub fn apply_update + Clone>( - &mut self, - update: ChainGraph, - ) -> Result, UpdateError

> { + pub fn apply_update(&mut self, update: ChainGraph

) -> Result, UpdateError

> { let changeset = self.determine_changeset(&update)?; self.apply_changeset(changeset.clone()); Ok(changeset) @@ -439,7 +427,7 @@ where /// Iterate over the full transactions and their position in the chain ordered by their position /// in ascending order. - pub fn transactions_in_chain(&self) -> impl DoubleEndedIterator { + pub fn transactions_in_chain(&self) -> impl DoubleEndedIterator { self.chain .txids() .map(move |(pos, txid)| (pos, self.graph.get_tx(*txid).expect("must exist"))) @@ -468,18 +456,18 @@ where serde( crate = "serde_crate", bound( - deserialize = "P: serde::Deserialize<'de>, T: Ord + serde::Deserialize<'de>", - serialize = "P: serde::Serialize, T: Ord + serde::Serialize" + deserialize = "P: serde::Deserialize<'de>", + serialize = "P: serde::Serialize" ) ) )] #[must_use] -pub struct ChangeSet { +pub struct ChangeSet

{ pub chain: sparse_chain::ChangeSet

, - pub graph: tx_graph::Additions, + pub graph: tx_graph::Additions, } -impl ChangeSet { +impl

ChangeSet

{ /// Returns `true` if this [`ChangeSet`] records no changes. pub fn is_empty(&self) -> bool { self.chain.is_empty() && self.graph.is_empty() @@ -495,17 +483,16 @@ impl ChangeSet { /// Appends the changes in `other` into self such that applying `self` afterwards has the same /// effect as sequentially applying the original `self` and `other`. - pub fn append(&mut self, other: ChangeSet) + pub fn append(&mut self, other: ChangeSet

) where P: ChainPosition, - T: Ord, { self.chain.append(other.chain); self.graph.append(other.graph); } } -impl Default for ChangeSet { +impl

Default for ChangeSet

{ fn default() -> Self { Self { chain: Default::default(), @@ -514,13 +501,13 @@ impl Default for ChangeSet { } } -impl ForEachTxOut for ChainGraph { +impl

ForEachTxOut for ChainGraph

{ fn for_each_txout(&self, f: impl FnMut((OutPoint, &TxOut))) { self.graph.for_each_txout(f) } } -impl ForEachTxOut for ChangeSet { +impl

ForEachTxOut for ChangeSet

{ fn for_each_txout(&self, f: impl FnMut((OutPoint, &TxOut))) { self.graph.for_each_txout(f) } diff --git a/crates/chain/src/keychain.rs b/crates/chain/src/keychain.rs index 68d5dd10..f2493826 100644 --- a/crates/chain/src/keychain.rs +++ b/crates/chain/src/keychain.rs @@ -19,9 +19,8 @@ use crate::{ collections::BTreeMap, sparse_chain::ChainPosition, tx_graph::TxGraph, - AsTransaction, ForEachTxOut, + ForEachTxOut, }; -use bitcoin::Transaction; #[cfg(feature = "miniscript")] pub mod persist; @@ -100,14 +99,14 @@ impl AsRef> for DerivationAdditions { #[derive(Clone, Debug, PartialEq)] /// An update that includes the last active indexes of each keychain. -pub struct KeychainScan { +pub struct KeychainScan { /// The update data in the form of a chain that could be applied - pub update: ChainGraph, + pub update: ChainGraph

, /// The last active indexes of each keychain pub last_active_indices: BTreeMap, } -impl Default for KeychainScan { +impl Default for KeychainScan { fn default() -> Self { Self { update: Default::default(), @@ -116,8 +115,8 @@ impl Default for KeychainScan { } } -impl From> for KeychainScan { - fn from(update: ChainGraph) -> Self { +impl From> for KeychainScan { + fn from(update: ChainGraph

) -> Self { KeychainScan { update, last_active_indices: Default::default(), @@ -135,20 +134,20 @@ impl From> for KeychainScan { serde( crate = "serde_crate", bound( - deserialize = "K: Ord + serde::Deserialize<'de>, P: serde::Deserialize<'de>, T: Ord + serde::Deserialize<'de>", - serialize = "K: Ord + serde::Serialize, P: serde::Serialize, T: Ord+ serde::Serialize" + deserialize = "K: Ord + serde::Deserialize<'de>, P: serde::Deserialize<'de>", + serialize = "K: Ord + serde::Serialize, P: serde::Serialize" ) ) )] #[must_use] -pub struct KeychainChangeSet { +pub struct KeychainChangeSet { /// The changes in local keychain derivation indices pub derivation_indices: DerivationAdditions, /// The changes that have occurred in the blockchain - pub chain_graph: chain_graph::ChangeSet, + pub chain_graph: chain_graph::ChangeSet

, } -impl Default for KeychainChangeSet { +impl Default for KeychainChangeSet { fn default() -> Self { Self { chain_graph: Default::default(), @@ -157,7 +156,7 @@ impl Default for KeychainChangeSet { } } -impl KeychainChangeSet { +impl KeychainChangeSet { /// Returns whether the [`KeychainChangeSet`] is empty (no changes recorded). pub fn is_empty(&self) -> bool { self.chain_graph.is_empty() && self.derivation_indices.is_empty() @@ -168,19 +167,18 @@ impl KeychainChangeSet { /// /// Note the derivation indices cannot be decreased so `other` will only change the derivation /// index for a keychain if it's entry is higher than the one in `self`. - pub fn append(&mut self, other: KeychainChangeSet) + pub fn append(&mut self, other: KeychainChangeSet) where K: Ord, P: ChainPosition, - T: Ord, { self.derivation_indices.append(other.derivation_indices); self.chain_graph.append(other.chain_graph); } } -impl From> for KeychainChangeSet { - fn from(changeset: chain_graph::ChangeSet) -> Self { +impl From> for KeychainChangeSet { + fn from(changeset: chain_graph::ChangeSet

) -> Self { Self { chain_graph: changeset, ..Default::default() @@ -188,7 +186,7 @@ impl From> for KeychainChangeSet } } -impl From> for KeychainChangeSet { +impl From> for KeychainChangeSet { fn from(additions: DerivationAdditions) -> Self { Self { derivation_indices: additions, @@ -197,13 +195,13 @@ impl From> for KeychainChangeSet { } } -impl AsRef> for KeychainScan { - fn as_ref(&self) -> &TxGraph { +impl AsRef for KeychainScan { + fn as_ref(&self) -> &TxGraph { self.update.graph() } } -impl ForEachTxOut for KeychainChangeSet { +impl ForEachTxOut for KeychainChangeSet { fn for_each_txout(&self, f: impl FnMut((bitcoin::OutPoint, &bitcoin::TxOut))) { self.chain_graph.for_each_txout(f) } @@ -267,8 +265,6 @@ impl core::ops::Add for Balance { #[cfg(test)] mod test { - use bitcoin::Transaction; - use crate::TxHeight; use super::*; @@ -291,12 +287,12 @@ mod test { rhs_di.insert(Keychain::Four, 4); let mut lhs = KeychainChangeSet { derivation_indices: DerivationAdditions(lhs_di), - chain_graph: chain_graph::ChangeSet::::default(), + chain_graph: chain_graph::ChangeSet::::default(), }; let rhs = KeychainChangeSet { derivation_indices: DerivationAdditions(rhs_di), - chain_graph: chain_graph::ChangeSet::::default(), + chain_graph: chain_graph::ChangeSet::::default(), }; lhs.append(rhs); diff --git a/crates/chain/src/keychain/tracker.rs b/crates/chain/src/keychain/tracker.rs index d360ff97..e75d299f 100644 --- a/crates/chain/src/keychain/tracker.rs +++ b/crates/chain/src/keychain/tracker.rs @@ -7,7 +7,7 @@ use crate::{ keychain::{KeychainChangeSet, KeychainScan, KeychainTxOutIndex}, sparse_chain::{self, SparseChain}, tx_graph::TxGraph, - AsTransaction, BlockId, FullTxOut, IntoOwned, TxHeight, + BlockId, FullTxOut, TxHeight, }; use super::{Balance, DerivationAdditions}; @@ -17,17 +17,16 @@ use super::{Balance, DerivationAdditions}; /// The [`KeychainTracker`] atomically updates its [`KeychainTxOutIndex`] whenever new chain data is /// incorporated into its internal [`ChainGraph`]. #[derive(Clone, Debug)] -pub struct KeychainTracker { +pub struct KeychainTracker { /// Index between script pubkeys to transaction outputs pub txout_index: KeychainTxOutIndex, - chain_graph: ChainGraph, + chain_graph: ChainGraph

, } -impl KeychainTracker +impl KeychainTracker where P: sparse_chain::ChainPosition, K: Ord + Clone + core::fmt::Debug, - T: AsTransaction + Clone + Ord, { /// Add a keychain to the tracker's `txout_index` with a descriptor to derive addresses for it. /// This is just shorthand for calling [`KeychainTxOutIndex::add_keychain`] on the internal @@ -63,13 +62,10 @@ where /// /// Internally, we call [`ChainGraph::determine_changeset`] and also determine the additions of /// [`KeychainTxOutIndex`]. - pub fn determine_changeset( + pub fn determine_changeset( &self, - scan: &KeychainScan, - ) -> Result, chain_graph::UpdateError

> - where - T2: IntoOwned + Clone, - { + scan: &KeychainScan, + ) -> Result, chain_graph::UpdateError

> { // TODO: `KeychainTxOutIndex::determine_additions` let mut derivation_indices = scan.last_active_indices.clone(); derivation_indices.retain(|keychain, index| { @@ -91,13 +87,10 @@ where /// /// [`determine_changeset`]: Self::determine_changeset /// [`apply_changeset`]: Self::apply_changeset - pub fn apply_update( + pub fn apply_update( &mut self, - scan: KeychainScan, - ) -> Result, chain_graph::UpdateError

> - where - T2: IntoOwned + Clone, - { + scan: KeychainScan, + ) -> Result, chain_graph::UpdateError

> { let changeset = self.determine_changeset(&scan)?; self.apply_changeset(changeset.clone()); Ok(changeset) @@ -107,7 +100,7 @@ where /// /// Internally, this calls [`KeychainTxOutIndex::apply_additions`] and /// [`ChainGraph::apply_changeset`] in sequence. - pub fn apply_changeset(&mut self, changeset: KeychainChangeSet) { + pub fn apply_changeset(&mut self, changeset: KeychainChangeSet) { let KeychainChangeSet { derivation_indices, chain_graph, @@ -139,12 +132,12 @@ where } /// Returns a reference to the internal [`ChainGraph`]. - pub fn chain_graph(&self) -> &ChainGraph { + pub fn chain_graph(&self) -> &ChainGraph

{ &self.chain_graph } /// Returns a reference to the internal [`TxGraph`] (which is part of the [`ChainGraph`]). - pub fn graph(&self) -> &TxGraph { + pub fn graph(&self) -> &TxGraph { self.chain_graph().graph() } @@ -166,7 +159,7 @@ where pub fn insert_checkpoint_preview( &self, block_id: BlockId, - ) -> Result, chain_graph::InsertCheckpointError> { + ) -> Result, chain_graph::InsertCheckpointError> { Ok(KeychainChangeSet { chain_graph: self.chain_graph.insert_checkpoint_preview(block_id)?, ..Default::default() @@ -183,7 +176,7 @@ where pub fn insert_checkpoint( &mut self, block_id: BlockId, - ) -> Result, chain_graph::InsertCheckpointError> { + ) -> Result, chain_graph::InsertCheckpointError> { let changeset = self.insert_checkpoint_preview(block_id)?; self.apply_changeset(changeset.clone()); Ok(changeset) @@ -196,9 +189,9 @@ where /// responsible for persisting these changes to disk if you need to restore them. pub fn insert_tx_preview( &self, - tx: T, + tx: Transaction, pos: P, - ) -> Result, chain_graph::InsertTxError

> { + ) -> Result, chain_graph::InsertTxError

> { Ok(KeychainChangeSet { chain_graph: self.chain_graph.insert_tx_preview(tx, pos)?, ..Default::default() @@ -214,9 +207,9 @@ where /// [`apply_changeset`]: Self::apply_changeset pub fn insert_tx( &mut self, - tx: T, + tx: Transaction, pos: P, - ) -> Result, chain_graph::InsertTxError

> { + ) -> Result, chain_graph::InsertTxError

> { let changeset = self.insert_tx_preview(tx, pos)?; self.apply_changeset(changeset.clone()); Ok(changeset) diff --git a/crates/chain/src/sparse_chain.rs b/crates/chain/src/sparse_chain.rs index 44af722f..32e9cce5 100644 --- a/crates/chain/src/sparse_chain.rs +++ b/crates/chain/src/sparse_chain.rs @@ -311,7 +311,7 @@ use core::{ ops::{Bound, RangeBounds}, }; -use crate::{collections::*, tx_graph::TxGraph, AsTransaction, BlockId, FullTxOut, TxHeight}; +use crate::{collections::*, tx_graph::TxGraph, BlockId, FullTxOut, TxHeight}; use bitcoin::{hashes::Hash, BlockHash, OutPoint, Txid}; /// This is a non-monotone structure that tracks relevant [`Txid`]s that are ordered by chain @@ -899,16 +899,12 @@ impl SparseChain

{ /// Attempt to retrieve a [`FullTxOut`] of the given `outpoint`. /// /// This will return `Some` only if the output's transaction is in both `self` and `graph`. - pub fn full_txout( - &self, - graph: &TxGraph, - outpoint: OutPoint, - ) -> Option> { + pub fn full_txout(&self, graph: &TxGraph, outpoint: OutPoint) -> Option> { let chain_pos = self.tx_position(outpoint.txid)?; let tx = graph.get_tx(outpoint.txid)?; - let is_on_coinbase = tx.as_tx().is_coin_base(); - let txout = tx.as_tx().output.get(outpoint.vout as usize)?.clone(); + let is_on_coinbase = tx.is_coin_base(); + let txout = tx.output.get(outpoint.vout as usize)?.clone(); let spent_by = self .spent_by(graph, outpoint) @@ -976,7 +972,7 @@ impl SparseChain

{ /// /// Note that the transaction including `outpoint` does not need to be in the `graph` or the /// `chain` for this to return `Some`. - pub fn spent_by(&self, graph: &TxGraph, outpoint: OutPoint) -> Option<(&P, Txid)> { + pub fn spent_by(&self, graph: &TxGraph, outpoint: OutPoint) -> Option<(&P, Txid)> { graph .outspends(outpoint) .iter() diff --git a/crates/chain/src/tx_data_traits.rs b/crates/chain/src/tx_data_traits.rs index af4fe3b6..db95a5d4 100644 --- a/crates/chain/src/tx_data_traits.rs +++ b/crates/chain/src/tx_data_traits.rs @@ -1,6 +1,3 @@ -use core::borrow::Borrow; - -use alloc::{borrow::Cow, boxed::Box, rc::Rc, sync::Arc}; use bitcoin::{Block, OutPoint, Transaction, TxOut}; /// Trait to do something with every txout contained in a structure. @@ -20,58 +17,10 @@ impl ForEachTxOut for Block { } } -/// Trait for things that have a single [`Transaction`] in them. -/// -/// This alows polymorphism in structures such as [`TxGraph`] where `T` can be anything that -/// implements `AsTransaction`. You might think that we could just use [`core::convert::AsRef`] for -/// this but the problem is that we need to implement it on `Cow` where `T: AsTransaction` which -/// we can't do with a foreign trait like `AsTransaction`. -/// -/// [`Transaction`]: bitcoin::Transaction -/// [`TxGraph`]: crate::tx_graph::TxGraph -pub trait AsTransaction { - /// Get a reference to the transaction. - fn as_tx(&self) -> &Transaction; -} - -impl AsTransaction for Transaction { - fn as_tx(&self) -> &Transaction { - self - } -} - -impl AsTransaction for Rc { - fn as_tx(&self) -> &Transaction { - self.as_ref().as_tx() - } -} - -impl AsTransaction for Arc { - fn as_tx(&self) -> &Transaction { - self.as_ref().as_tx() - } -} - -impl AsTransaction for Box { - fn as_tx(&self) -> &Transaction { - self.as_ref().as_tx() - } -} - -impl<'a, T: AsTransaction + Clone> AsTransaction for Cow<'a, T> { - fn as_tx(&self) -> &Transaction { - as Borrow>::borrow(self).as_tx() - } -} - -impl ForEachTxOut for T -where - T: AsTransaction, -{ +impl ForEachTxOut for Transaction { fn for_each_txout(&self, mut f: impl FnMut((OutPoint, &TxOut))) { - let tx = self.as_tx(); - let txid = tx.txid(); - for (i, txout) in tx.output.iter().enumerate() { + let txid = self.txid(); + for (i, txout) in self.output.iter().enumerate() { f(( OutPoint { txid, @@ -82,34 +31,3 @@ where } } } - -/// A trait like [`core::convert::Into`] for converting one thing into another. -/// -/// We use it to convert one transaction type into another so that an update for `T2` can be used on -/// a `TxGraph` as long as `T2: IntoOwned`. -/// -/// We couldn't use `Into` because we needed to implement it for [`Cow<'a, T>`]. -/// -/// [`Cow<'a, T>`]: std::borrow::Cow -pub trait IntoOwned { - /// Converts the provided type into another (owned) type. - fn into_owned(self) -> T; -} - -impl IntoOwned for T { - fn into_owned(self) -> T { - self - } -} - -impl<'a, T: Clone> IntoOwned for Cow<'a, T> { - fn into_owned(self) -> T { - Cow::into_owned(self) - } -} - -impl<'a, T: Clone> IntoOwned for &'a T { - fn into_owned(self) -> T { - self.clone() - } -} diff --git a/crates/chain/src/tx_graph.rs b/crates/chain/src/tx_graph.rs index 1857a8d0..16a5c8fe 100644 --- a/crates/chain/src/tx_graph.rs +++ b/crates/chain/src/tx_graph.rs @@ -20,7 +20,7 @@ //! # 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::::default(); +//! let mut graph = TxGraph::default(); //! //! // preview a transaction insertion (not actually inserted) //! let additions = graph.insert_tx_preview(tx_a); @@ -39,8 +39,8 @@ //! # 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::::default(); -//! let update = TxGraph::::new(vec![tx_a, tx_b]); +//! let mut graph = TxGraph::default(); +//! let update = TxGraph::new(vec![tx_a, tx_b]); //! //! // preview additions as result of the update //! let additions = graph.determine_additions(&update); @@ -52,7 +52,7 @@ //! let additions = graph.apply_update(update); //! assert!(additions.is_empty()); //! ``` -use crate::{collections::*, AsTransaction, ForEachTxOut, IntoOwned}; +use crate::{collections::*, ForEachTxOut}; use alloc::vec::Vec; use bitcoin::{OutPoint, Transaction, TxOut, Txid}; use core::ops::RangeInclusive; @@ -63,8 +63,8 @@ use core::ops::RangeInclusive; /// /// [module-level documentation]: crate::tx_graph #[derive(Clone, Debug, PartialEq)] -pub struct TxGraph { - txs: HashMap>, +pub struct TxGraph { + txs: HashMap, spends: BTreeMap>, // This atrocity exists so that `TxGraph::outspends()` can return a reference. @@ -72,7 +72,7 @@ pub struct TxGraph { empty_outspends: HashSet, } -impl Default for TxGraph { +impl Default for TxGraph { fn default() -> Self { Self { txs: Default::default(), @@ -85,23 +85,22 @@ impl Default for TxGraph { /// Node of a [`TxGraph`]. This can either be a whole transaction, or a partial transaction (where /// we only have select outputs). #[derive(Clone, Debug, PartialEq)] -enum TxNode { - Whole(T), +enum TxNode { + Whole(Transaction), Partial(BTreeMap), } -impl Default for TxNode { +impl Default for TxNode { fn default() -> Self { Self::Partial(BTreeMap::new()) } } -impl TxGraph { +impl TxGraph { /// Iterate over all tx outputs known by [`TxGraph`]. pub fn all_txouts(&self) -> impl Iterator { self.txs.iter().flat_map(|(txid, tx)| match tx { TxNode::Whole(tx) => tx - .as_tx() .output .iter() .enumerate() @@ -115,7 +114,7 @@ impl TxGraph { } /// Iterate over all full transactions in the graph. - pub fn full_transactions(&self) -> impl Iterator { + pub fn full_transactions(&self) -> impl Iterator { self.txs.iter().filter_map(|(_, tx)| match tx { TxNode::Whole(tx) => Some(tx), TxNode::Partial(_) => None, @@ -127,7 +126,7 @@ impl TxGraph { /// Refer to [`get_txout`] for getting a specific [`TxOut`]. /// /// [`get_txout`]: Self::get_txout - pub fn get_tx(&self, txid: Txid) -> Option<&T> { + pub fn get_tx(&self, txid: Txid) -> Option<&Transaction> { match self.txs.get(&txid)? { TxNode::Whole(tx) => Some(tx), TxNode::Partial(_) => None, @@ -137,7 +136,7 @@ impl TxGraph { /// Obtains a single tx output (if any) at specified outpoint. pub fn get_txout(&self, outpoint: OutPoint) -> Option<&TxOut> { match self.txs.get(&outpoint.txid)? { - TxNode::Whole(tx) => tx.as_tx().output.get(outpoint.vout as usize), + TxNode::Whole(tx) => tx.output.get(outpoint.vout as usize), TxNode::Partial(txouts) => txouts.get(&outpoint.vout), } } @@ -146,7 +145,6 @@ impl TxGraph { pub fn txouts(&self, txid: Txid) -> Option> { Some(match self.txs.get(&txid)? { TxNode::Whole(tx) => tx - .as_tx() .output .iter() .enumerate() @@ -190,9 +188,9 @@ impl TxGraph { } } -impl TxGraph { +impl TxGraph { /// Contruct a new [`TxGraph`] from a list of transaction. - pub fn new(txs: impl IntoIterator) -> Self { + pub fn new(txs: impl IntoIterator) -> Self { let mut new = Self::default(); for tx in txs.into_iter() { let _ = new.insert_tx(tx); @@ -203,7 +201,7 @@ impl TxGraph { /// /// Note this will ignore the action if we already have the full transaction that the txout is /// alledged to be on (even if it doesn't match it!). - pub fn insert_txout(&mut self, outpoint: OutPoint, txout: TxOut) -> 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 @@ -212,7 +210,7 @@ impl TxGraph { /// Inserts the given transaction into [`TxGraph`]. /// /// The [`Additions`] returned will be empty if `tx` already exists. - pub fn insert_tx(&mut self, tx: T) -> Additions { + pub fn insert_tx(&mut self, tx: Transaction) -> Additions { let additions = self.insert_tx_preview(tx); self.apply_additions(additions.clone()); additions @@ -223,22 +221,18 @@ impl TxGraph { /// /// The returned [`Additions`] is the set difference of `update` and `self` (transactions that /// exist in `update` but not in `self`). - pub fn apply_update(&mut self, update: TxGraph) -> Additions - where - T2: IntoOwned + Clone, - { + pub fn apply_update(&mut self, update: TxGraph) -> Additions { let additions = self.determine_additions(&update); self.apply_additions(additions.clone()); additions } /// Applies [`Additions`] to [`TxGraph`]. - pub fn apply_additions(&mut self, additions: Additions) { + pub fn apply_additions(&mut self, additions: Additions) { for tx in additions.tx { - let txid = tx.as_tx().txid(); + let txid = tx.txid(); - tx.as_tx() - .input + tx.input .iter() .map(|txin| txin.previous_output) // coinbase spends are not to be counted @@ -250,7 +244,7 @@ impl TxGraph { if let Some(TxNode::Whole(old_tx)) = self.txs.insert(txid, TxNode::Whole(tx)) { debug_assert_eq!( - old_tx.as_tx().txid(), + old_tx.txid(), txid, "old tx of same txid should not be different" ); @@ -276,11 +270,8 @@ impl TxGraph { /// /// The [`Additions`] would be the set difference of `update` and `self` (transactions that /// exist in `update` but not in `self`). - pub fn determine_additions(&self, update: &TxGraph) -> Additions - where - T2: IntoOwned + Clone, - { - let mut additions = Additions::::default(); + pub fn determine_additions(&self, update: &TxGraph) -> Additions { + let mut additions = Additions::default(); for (&txid, update_tx) in &update.txs { if self.get_tx(txid).is_some() { @@ -290,9 +281,7 @@ impl TxGraph { match update_tx { TxNode::Whole(tx) => { if matches!(self.txs.get(&txid), None | Some(TxNode::Partial(_))) { - additions - .tx - .insert(>::into_owned(tx.clone())); + additions.tx.insert(tx.clone()); } } TxNode::Partial(partial) => { @@ -314,9 +303,9 @@ impl TxGraph { /// mutate [`Self`]. /// /// The [`Additions`] result will be empty if `tx` already existed in `self`. - pub fn insert_tx_preview(&self, tx: T) -> Additions { + pub fn insert_tx_preview(&self, tx: Transaction) -> Additions { let mut update = Self::default(); - update.txs.insert(tx.as_tx().txid(), TxNode::Whole(tx)); + update.txs.insert(tx.txid(), TxNode::Whole(tx)); self.determine_additions(&update) } @@ -325,7 +314,7 @@ impl TxGraph { /// /// The [`Additions`] 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 { + pub fn insert_txout_preview(&self, outpoint: OutPoint, txout: TxOut) -> Additions { let mut update = Self::default(); update.txs.insert( outpoint.txid, @@ -335,7 +324,7 @@ impl TxGraph { } } -impl TxGraph { +impl TxGraph { /// The transactions spending from this output. /// /// `TxGraph` allows conflicting transactions within the graph. Obviously the transactions in @@ -382,7 +371,7 @@ impl TxGraph { /// /// The supplied closure returns an `Option`, allowing the caller to map each node it vists /// and decide whether to visit descendants. - pub fn walk_descendants<'g, F, O>(&'g self, txid: Txid, walk_map: F) -> TxDescendants + pub fn walk_descendants<'g, F, O>(&'g self, txid: Txid, walk_map: F) -> TxDescendants where F: FnMut(usize, Txid) -> Option + 'g, { @@ -393,11 +382,7 @@ impl TxGraph { /// descendants of directly-conflicting transactions, which are also considered conflicts). /// /// Refer to [`Self::walk_descendants`] for `walk_map` usage. - pub fn walk_conflicts<'g, F, O>( - &'g self, - tx: &'g Transaction, - walk_map: F, - ) -> TxDescendants + pub fn walk_conflicts<'g, F, O>(&'g self, tx: &'g Transaction, walk_map: F) -> TxDescendants where F: FnMut(usize, Txid) -> Option + 'g, { @@ -442,55 +427,42 @@ impl TxGraph { #[cfg_attr( feature = "serde", derive(serde::Deserialize, serde::Serialize), - serde( - crate = "serde_crate", - bound( - deserialize = "T: Ord + serde::Deserialize<'de>", - serialize = "T: Ord + serde::Serialize" - ) - ) + serde(crate = "serde_crate") )] #[must_use] -pub struct Additions { - pub tx: BTreeSet, +pub struct Additions { + pub tx: BTreeSet, pub txout: BTreeMap, } -impl Additions { +impl Additions { /// Returns true if the [`Additions`] is empty (no transactions or txouts). pub fn is_empty(&self) -> bool { self.tx.is_empty() && self.txout.is_empty() } /// Iterates over all outpoints contained within [`Additions`]. - pub fn txouts(&self) -> impl Iterator - where - T: AsTransaction, - { + pub fn txouts(&self) -> impl Iterator { self.tx .iter() .flat_map(|tx| { - tx.as_tx() - .output + tx.output .iter() .enumerate() - .map(move |(vout, txout)| (OutPoint::new(tx.as_tx().txid(), vout as _), txout)) + .map(move |(vout, txout)| (OutPoint::new(tx.txid(), vout as _), txout)) }) .chain(self.txout.iter().map(|(op, txout)| (*op, txout))) } /// Appends the changes in `other` into self such that applying `self` afterwards has the same /// effect as sequentially applying the original `self` and `other`. - pub fn append(&mut self, mut other: Additions) - where - T: Ord, - { + pub fn append(&mut self, mut other: Additions) { self.tx.append(&mut other.tx); self.txout.append(&mut other.txout); } } -impl Default for Additions { +impl Default for Additions { fn default() -> Self { Self { tx: Default::default(), @@ -505,13 +477,13 @@ impl AsRef for TxGraph { } } -impl ForEachTxOut for Additions { +impl ForEachTxOut for Additions { fn for_each_txout(&self, f: impl FnMut((OutPoint, &TxOut))) { self.txouts().for_each(f) } } -impl ForEachTxOut for TxGraph { +impl ForEachTxOut for TxGraph { fn for_each_txout(&self, f: impl FnMut((OutPoint, &TxOut))) { self.all_txouts().for_each(f) } @@ -522,17 +494,17 @@ impl ForEachTxOut for TxGraph { /// This `struct` is created by the [`walk_descendants`] method of [`TxGraph`]. /// /// [`walk_descendants`]: TxGraph::walk_descendants -pub struct TxDescendants<'g, F, T> { - graph: &'g TxGraph, +pub struct TxDescendants<'g, F> { + graph: &'g TxGraph, visited: HashSet, stack: Vec<(usize, Txid)>, filter_map: F, } -impl<'g, F, T> TxDescendants<'g, F, T> { +impl<'g, F> TxDescendants<'g, F> { /// Creates a `TxDescendants` that includes the starting `txid` when iterating. #[allow(unused)] - pub(crate) fn new_include_root(graph: &'g TxGraph, txid: Txid, filter_map: F) -> Self { + pub(crate) fn new_include_root(graph: &'g TxGraph, txid: Txid, filter_map: F) -> Self { Self { graph, visited: Default::default(), @@ -542,7 +514,7 @@ impl<'g, F, T> TxDescendants<'g, F, T> { } /// Creates a `TxDescendants` that excludes the starting `txid` when iterating. - pub(crate) fn new_exclude_root(graph: &'g TxGraph, txid: Txid, filter_map: F) -> Self { + pub(crate) fn new_exclude_root(graph: &'g TxGraph, txid: Txid, filter_map: F) -> Self { let mut descendants = Self { graph, visited: Default::default(), @@ -555,11 +527,7 @@ impl<'g, F, T> TxDescendants<'g, F, T> { /// Creates a `TxDescendants` from multiple starting transactions that includes the starting /// `txid`s when iterating. - pub(crate) fn from_multiple_include_root( - graph: &'g TxGraph, - txids: I, - filter_map: F, - ) -> Self + pub(crate) fn from_multiple_include_root(graph: &'g TxGraph, txids: I, filter_map: F) -> Self where I: IntoIterator, { @@ -574,11 +542,7 @@ impl<'g, F, T> TxDescendants<'g, F, T> { /// Creates a `TxDescendants` from multiple starting transactions that excludes the starting /// `txid`s when iterating. #[allow(unused)] - pub(crate) fn from_multiple_exclude_root( - graph: &'g TxGraph, - txids: I, - filter_map: F, - ) -> Self + pub(crate) fn from_multiple_exclude_root(graph: &'g TxGraph, txids: I, filter_map: F) -> Self where I: IntoIterator, { @@ -595,7 +559,7 @@ impl<'g, F, T> TxDescendants<'g, F, T> { } } -impl<'g, F, T> TxDescendants<'g, F, T> { +impl<'g, F> TxDescendants<'g, F> { fn populate_stack(&mut self, depth: usize, txid: Txid) { let spend_paths = self .graph @@ -607,7 +571,7 @@ impl<'g, F, T> TxDescendants<'g, F, T> { } } -impl<'g, F, O, T> Iterator for TxDescendants<'g, F, T> +impl<'g, F, O> Iterator for TxDescendants<'g, F> where F: FnMut(usize, Txid) -> Option, { diff --git a/crates/chain/tests/test_chain_graph.rs b/crates/chain/tests/test_chain_graph.rs index d966989d..68f50b8f 100644 --- a/crates/chain/tests/test_chain_graph.rs +++ b/crates/chain/tests/test_chain_graph.rs @@ -124,7 +124,7 @@ fn update_evicts_conflicting_tx() { cg }; - let changeset = ChangeSet:: { + let changeset = ChangeSet:: { chain: sparse_chain::ChangeSet { checkpoints: Default::default(), txids: [ @@ -203,7 +203,7 @@ fn update_evicts_conflicting_tx() { cg }; - let changeset = ChangeSet:: { + let changeset = ChangeSet:: { chain: sparse_chain::ChangeSet { checkpoints: [(1, Some(h!("B'")))].into(), txids: [ @@ -287,7 +287,7 @@ fn chain_graph_new_missing() { let new_graph = ChainGraph::new(update.clone(), graph.clone()).unwrap(); let expected_graph = { - let mut cg = ChainGraph::::default(); + let mut cg = ChainGraph::::default(); let _ = cg .insert_checkpoint(update.latest_checkpoint().unwrap()) .unwrap(); diff --git a/crates/chain/tests/test_tx_graph.rs b/crates/chain/tests/test_tx_graph.rs index ea404e60..04974bf3 100644 --- a/crates/chain/tests/test_tx_graph.rs +++ b/crates/chain/tests/test_tx_graph.rs @@ -35,7 +35,7 @@ fn insert_txouts() { )]; let mut graph = { - let mut graph = TxGraph::::default(); + let mut graph = TxGraph::default(); for (outpoint, txout) in &original_ops { assert_eq!( graph.insert_txout(*outpoint, txout.clone()), @@ -49,7 +49,7 @@ fn insert_txouts() { }; let update = { - let mut graph = TxGraph::::default(); + let mut graph = TxGraph::default(); for (outpoint, txout) in &update_ops { assert_eq!( graph.insert_txout(*outpoint, txout.clone()), @@ -362,7 +362,7 @@ fn test_calculate_fee_on_coinbase() { output: vec![TxOut::default()], }; - let graph = TxGraph::::default(); + let graph = TxGraph::default(); assert_eq!(graph.calculate_fee(&tx), Some(0)); } diff --git a/crates/electrum/src/lib.rs b/crates/electrum/src/lib.rs index 9f5061ca..288c05c6 100644 --- a/crates/electrum/src/lib.rs +++ b/crates/electrum/src/lib.rs @@ -32,7 +32,7 @@ use bdk_chain::{ keychain::KeychainScan, sparse_chain::{self, ChainPosition, SparseChain}, tx_graph::TxGraph, - AsTransaction, BlockId, ConfirmationTime, TxHeight, + BlockId, ConfirmationTime, TxHeight, }; pub use electrum_client; use electrum_client::{Client, ElectrumApi, Error}; @@ -228,10 +228,9 @@ impl ElectrumUpdate { /// Return a list of missing full transactions that are required to [`inflate_update`]. /// /// [`inflate_update`]: bdk_chain::chain_graph::ChainGraph::inflate_update - pub fn missing_full_txs(&self, graph: G) -> Vec<&Txid> + pub fn missing_full_txs(&self, graph: G) -> Vec<&Txid> where - T: AsTransaction, - G: AsRef>, + G: AsRef, { self.chain_update .txids() @@ -244,14 +243,13 @@ impl ElectrumUpdate { /// `tracker`. /// /// This will fail if there are missing full transactions not provided via `new_txs`. - pub fn into_keychain_scan( + pub fn into_keychain_scan( self, - new_txs: Vec, + new_txs: Vec, chain_graph: &CG, - ) -> Result, chain_graph::NewError

> + ) -> Result, chain_graph::NewError

> where - T: AsTransaction + Clone + Ord, - CG: AsRef>, + CG: AsRef>, { Ok(KeychainScan { update: chain_graph diff --git a/crates/file_store/src/file_store.rs b/crates/file_store/src/file_store.rs index 37855506..f9a8056b 100644 --- a/crates/file_store/src/file_store.rs +++ b/crates/file_store/src/file_store.rs @@ -3,9 +3,8 @@ //! The star of the show is [`KeychainStore`] which maintains an append-only file of //! [`KeychainChangeSet`]s which can be used to restore a [`KeychainTracker`]. use bdk_chain::{ - bitcoin::Transaction, keychain::{KeychainChangeSet, KeychainTracker}, - sparse_chain, AsTransaction, + sparse_chain, }; use bincode::{DefaultOptions, Options}; use core::marker::PhantomData; @@ -24,21 +23,20 @@ const MAGIC_BYTES: [u8; MAGIC_BYTES_LEN] = [98, 100, 107, 102, 115, 48, 48, 48, /// Persists an append only list of `KeychainChangeSet` to a single file. /// [`KeychainChangeSet`] record the changes made to a [`KeychainTracker`]. #[derive(Debug)] -pub struct KeychainStore { +pub struct KeychainStore { db_file: File, - changeset_type_params: core::marker::PhantomData<(K, P, T)>, + changeset_type_params: core::marker::PhantomData<(K, P)>, } fn bincode() -> impl bincode::Options { DefaultOptions::new().with_varint_encoding() } -impl KeychainStore +impl KeychainStore where K: Ord + Clone + core::fmt::Debug, P: sparse_chain::ChainPosition, - T: Ord + AsTransaction + Clone, - KeychainChangeSet: serde::Serialize + serde::de::DeserializeOwned, + KeychainChangeSet: serde::Serialize + serde::de::DeserializeOwned, { /// Creates a new store from a [`File`]. /// @@ -87,9 +85,7 @@ where /// **WARNING**: This method changes the write position in the underlying file. You should /// always iterate over all entries until `None` is returned if you want your next write to go /// at the end, otherwise you will write over existing enties. - pub fn iter_changesets( - &mut self, - ) -> Result>, io::Error> { + pub fn iter_changesets(&mut self) -> Result>, io::Error> { self.db_file .seek(io::SeekFrom::Start(MAGIC_BYTES_LEN as _))?; @@ -108,7 +104,7 @@ where /// /// **WARNING**: This method changes the write position of the underlying file. The next /// changeset will be written over the erroring entry (or the end of the file if none existed). - pub fn aggregate_changeset(&mut self) -> (KeychainChangeSet, Result<(), IterError>) { + pub fn aggregate_changeset(&mut self) -> (KeychainChangeSet, Result<(), IterError>) { let mut changeset = KeychainChangeSet::default(); let result = (|| { let iter_changeset = self.iter_changesets()?; @@ -128,7 +124,7 @@ where /// changeset will be written over the erroring entry (or the end of the file if none existed). pub fn load_into_keychain_tracker( &mut self, - tracker: &mut KeychainTracker, + tracker: &mut KeychainTracker, ) -> Result<(), IterError> { for changeset in self.iter_changesets()? { tracker.apply_changeset(changeset?) @@ -142,7 +138,7 @@ where /// directly after the appended changeset. pub fn append_changeset( &mut self, - changeset: &KeychainChangeSet, + changeset: &KeychainChangeSet, ) -> Result<(), io::Error> { if changeset.is_empty() { return Ok(()); @@ -291,7 +287,6 @@ impl From for IterError { mod test { use super::*; use bdk_chain::{ - bitcoin::Transaction, keychain::{DerivationAdditions, KeychainChangeSet}, TxHeight, }; @@ -337,7 +332,7 @@ mod test { file.write_all(&MAGIC_BYTES[..MAGIC_BYTES_LEN - 1]) .expect("should write"); - match KeychainStore::::new(file.reopen().unwrap()) { + match KeychainStore::::new(file.reopen().unwrap()) { Err(FileError::Io(e)) => assert_eq!(e.kind(), std::io::ErrorKind::UnexpectedEof), unexpected => panic!("unexpected result: {:?}", unexpected), }; @@ -351,7 +346,7 @@ mod test { file.write_all(invalid_magic_bytes.as_bytes()) .expect("should write"); - match KeychainStore::::new(file.reopen().unwrap()) { + match KeychainStore::::new(file.reopen().unwrap()) { Err(FileError::InvalidMagicBytes(b)) => { assert_eq!(b, invalid_magic_bytes.as_bytes()) } @@ -375,9 +370,8 @@ mod test { let mut file = NamedTempFile::new().unwrap(); file.write_all(&data).expect("should write"); - let mut store = - KeychainStore::::new(file.reopen().unwrap()) - .expect("should open"); + let mut store = KeychainStore::::new(file.reopen().unwrap()) + .expect("should open"); match store.iter_changesets().expect("seek should succeed").next() { Some(Err(IterError::Bincode(_))) => {} unexpected_res => panic!("unexpected result: {:?}", unexpected_res), diff --git a/crates/file_store/src/lib.rs b/crates/file_store/src/lib.rs index a1ad7a34..85dc5229 100644 --- a/crates/file_store/src/lib.rs +++ b/crates/file_store/src/lib.rs @@ -1,6 +1,5 @@ mod file_store; use bdk_chain::{ - bitcoin::Transaction, keychain::{KeychainChangeSet, KeychainTracker, PersistBackend}, sparse_chain::ChainPosition, }; @@ -10,7 +9,7 @@ impl PersistBackend for KeychainStore where K: Ord + Clone + core::fmt::Debug, P: ChainPosition, - KeychainChangeSet: serde::Serialize + serde::de::DeserializeOwned, + KeychainChangeSet: serde::Serialize + serde::de::DeserializeOwned, { type WriteError = std::io::Error;