]> Untitled Git - bdk/commitdiff
refactor: move WalletChangeset to wallet module
authorVladimir Fomene <vladimirfomene@gmail.com>
Mon, 21 Aug 2023 12:18:16 +0000 (15:18 +0300)
committer志宇 <hello@evanlinjin.me>
Sat, 2 Sep 2023 17:48:01 +0000 (01:48 +0800)
Consequently, remove the `WalletChangeset` dependency from
`example_electrum` and `example_esplora` examples.

crates/bdk/src/wallet/mod.rs
crates/chain/src/keychain.rs
crates/chain/src/lib.rs
example-crates/example_electrum/src/main.rs
example-crates/example_esplora/src/main.rs

index 1fe16147a8b31b873d6c9b71f581aa987eb28f24..47dd03de201dba3f6656f3aa99eef42b68c0ca46 100644 (file)
@@ -22,10 +22,10 @@ use alloc::{
 pub use bdk_chain::keychain::Balance;
 use bdk_chain::{
     indexed_tx_graph,
-    keychain::{KeychainTxOutIndex, WalletChangeSet},
+    keychain::{self, KeychainTxOutIndex},
     local_chain::{self, CannotConnectError, CheckPoint, CheckPointIter, LocalChain},
     tx_graph::{CanonicalTx, TxGraph},
-    Append, BlockId, ChainPosition, ConfirmationTime, ConfirmationTimeAnchor, FullTxOut,
+    Anchor, Append, BlockId, ChainPosition, ConfirmationTime, ConfirmationTimeAnchor, FullTxOut,
     IndexedTxGraph, Persist, PersistBackend,
 };
 use bitcoin::consensus::encode::serialize;
@@ -124,6 +124,62 @@ impl<K, A> WalletUpdate<K, A> {
     }
 }
 
+/// A structure that records the corresponding changes as result of applying an [`WalletUpdate`].
+#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
+pub struct WalletChangeSet<K, A> {
+    /// Changes to the [`LocalChain`].
+    ///
+    /// [`LocalChain`]: local_chain::LocalChain
+    pub chain: local_chain::ChangeSet,
+
+    /// ChangeSet to [`IndexedTxGraph`].
+    ///
+    /// [`IndexedTxGraph`]: bdk_chain::indexed_tx_graph::IndexedTxGraph
+    #[serde(bound(
+        deserialize = "K: Ord + serde::Deserialize<'de>, A: Ord + serde::Deserialize<'de>",
+        serialize = "K: Ord + serde::Serialize, A: Ord + serde::Serialize",
+    ))]
+    pub index_tx_graph: indexed_tx_graph::ChangeSet<A, keychain::ChangeSet<K>>,
+}
+
+impl<K, A> Default for WalletChangeSet<K, A> {
+    fn default() -> Self {
+        Self {
+            chain: Default::default(),
+            index_tx_graph: Default::default(),
+        }
+    }
+}
+
+impl<K: Ord, A: Anchor> Append for WalletChangeSet<K, A> {
+    fn append(&mut self, other: Self) {
+        Append::append(&mut self.chain, other.chain);
+        Append::append(&mut self.index_tx_graph, other.index_tx_graph);
+    }
+
+    fn is_empty(&self) -> bool {
+        self.chain.is_empty() && self.index_tx_graph.is_empty()
+    }
+}
+
+impl<K, A> From<local_chain::ChangeSet> for WalletChangeSet<K, A> {
+    fn from(chain: local_chain::ChangeSet) -> Self {
+        Self {
+            chain,
+            ..Default::default()
+        }
+    }
+}
+
+impl<K, A> From<indexed_tx_graph::ChangeSet<A, keychain::ChangeSet<K>>> for WalletChangeSet<K, A> {
+    fn from(index_tx_graph: indexed_tx_graph::ChangeSet<A, keychain::ChangeSet<K>>) -> Self {
+        Self {
+            index_tx_graph,
+            ..Default::default()
+        }
+    }
+}
+
 /// The update to a [`Wallet`] used in [`Wallet::apply_update`]. This is usually returned from blockchain data sources.
 pub type Update = WalletUpdate<KeychainKind, ConfirmationTimeAnchor>;
 
@@ -277,7 +333,7 @@ impl<D> Wallet<D> {
 
         let changeset = db.load_from_persistence().map_err(NewError::Persist)?;
         chain.apply_changeset(&changeset.chain);
-        indexed_graph.apply_changeset(changeset.indexed_tx_graph);
+        indexed_graph.apply_changeset(changeset.index_tx_graph);
 
         let persist = Persist::new(db);
 
index 74e982429f153c2030c65bdcacbd860dda821a40..63972a0ade3bb72a60ebd4f50b36d4c9eb19df8f 100644 (file)
@@ -10,7 +10,7 @@
 //!
 //! [`SpkTxOutIndex`]: crate::SpkTxOutIndex
 
-use crate::{collections::BTreeMap, indexed_tx_graph, local_chain, Anchor, Append};
+use crate::{collections::BTreeMap, Append};
 
 #[cfg(feature = "miniscript")]
 mod txout_index;
@@ -80,69 +80,6 @@ impl<K> AsRef<BTreeMap<K, u32>> for ChangeSet<K> {
     }
 }
 
-/// A structure that records the corresponding changes as result of applying an [`WalletUpdate`].
-#[derive(Debug, Clone, PartialEq)]
-#[cfg_attr(
-    feature = "serde",
-    derive(serde::Deserialize, serde::Serialize),
-    serde(
-        crate = "serde_crate",
-        bound(
-            deserialize = "K: Ord + serde::Deserialize<'de>, A: Ord + serde::Deserialize<'de>",
-            serialize = "K: Ord + serde::Serialize, A: Ord + serde::Serialize",
-        )
-    )
-)]
-pub struct WalletChangeSet<K, A> {
-    /// Changes to the [`LocalChain`].
-    ///
-    /// [`LocalChain`]: local_chain::LocalChain
-    pub chain: local_chain::ChangeSet,
-
-    /// ChangeSet to [`IndexedTxGraph`].
-    ///
-    /// [`IndexedTxGraph`]: crate::indexed_tx_graph::IndexedTxGraph
-    pub indexed_tx_graph: indexed_tx_graph::ChangeSet<A, ChangeSet<K>>,
-}
-
-impl<K, A> Default for WalletChangeSet<K, A> {
-    fn default() -> Self {
-        Self {
-            chain: Default::default(),
-            indexed_tx_graph: Default::default(),
-        }
-    }
-}
-
-impl<K: Ord, A: Anchor> Append for WalletChangeSet<K, A> {
-    fn append(&mut self, other: Self) {
-        Append::append(&mut self.chain, other.chain);
-        Append::append(&mut self.indexed_tx_graph, other.indexed_tx_graph);
-    }
-
-    fn is_empty(&self) -> bool {
-        self.chain.is_empty() && self.indexed_tx_graph.is_empty()
-    }
-}
-
-impl<K, A> From<local_chain::ChangeSet> for WalletChangeSet<K, A> {
-    fn from(chain: local_chain::ChangeSet) -> Self {
-        Self {
-            chain,
-            ..Default::default()
-        }
-    }
-}
-
-impl<K, A> From<indexed_tx_graph::ChangeSet<A, ChangeSet<K>>> for WalletChangeSet<K, A> {
-    fn from(indexed_tx_graph: indexed_tx_graph::ChangeSet<A, ChangeSet<K>>) -> Self {
-        Self {
-            indexed_tx_graph,
-            ..Default::default()
-        }
-    }
-}
-
 /// Balance, differentiated into various categories.
 #[derive(Debug, PartialEq, Eq, Clone, Default)]
 #[cfg_attr(
index ed167ebf6c114851d6c3720357d48a931728c538..f38b7ee53dc1469cdb66af3f465c365d0b7a11c4 100644 (file)
@@ -100,3 +100,11 @@ pub mod collections {
 
 /// How many confirmations are needed f or a coinbase output to be spent.
 pub const COINBASE_MATURITY: u32 = 100;
+
+impl<A, IA> From<indexed_tx_graph::ChangeSet<A, IA>>
+    for (local_chain::ChangeSet, indexed_tx_graph::ChangeSet<A, IA>)
+{
+    fn from(indexed_changeset: indexed_tx_graph::ChangeSet<A, IA>) -> Self {
+        (local_chain::ChangeSet::default(), indexed_changeset)
+    }
+}
index 56cc144c4bf36081409c30276c40c0cf0fef1f37..f8bb10b1e4110338e740d7bef5f9e15464e02ddf 100644 (file)
@@ -7,7 +7,7 @@ use std::{
 use bdk_chain::{
     bitcoin::{Address, Network, OutPoint, ScriptBuf, Txid},
     indexed_tx_graph::{self, IndexedTxGraph},
-    keychain::WalletChangeSet,
+    keychain,
     local_chain::{self, LocalChain},
     Append, ConfirmationHeightAnchor,
 };
@@ -60,7 +60,10 @@ pub struct ScanOptions {
     pub batch_size: usize,
 }
 
-type ChangeSet = WalletChangeSet<Keychain, ConfirmationHeightAnchor>;
+type ChangeSet = (
+    local_chain::ChangeSet,
+    indexed_tx_graph::ChangeSet<ConfirmationHeightAnchor, keychain::ChangeSet<Keychain>>,
+);
 
 fn main() -> anyhow::Result<()> {
     let (args, keymap, index, db, init_changeset) =
@@ -68,11 +71,11 @@ fn main() -> anyhow::Result<()> {
 
     let graph = Mutex::new({
         let mut graph = IndexedTxGraph::new(index);
-        graph.apply_changeset(init_changeset.indexed_tx_graph);
+        graph.apply_changeset(init_changeset.1);
         graph
     });
 
-    let chain = Mutex::new(LocalChain::from_changeset(init_changeset.chain));
+    let chain = Mutex::new(LocalChain::from_changeset(init_changeset.0));
 
     let electrum_url = match args.network {
         Network::Bitcoin => "ssl://electrum.blockstream.info:50002",
@@ -293,10 +296,7 @@ fn main() -> anyhow::Result<()> {
             changeset
         };
 
-        ChangeSet {
-            indexed_tx_graph,
-            chain,
-        }
+        (chain, indexed_tx_graph)
     };
 
     let mut db = db.lock().unwrap();
index f33125be8e6fc402fe839d6dc91645a70d1a0b22..9559e1d320455d785a19438eae4361721d01e8d8 100644 (file)
@@ -6,9 +6,9 @@ use std::{
 
 use bdk_chain::{
     bitcoin::{Address, Network, OutPoint, ScriptBuf, Txid},
-    indexed_tx_graph::IndexedTxGraph,
-    keychain::WalletChangeSet,
-    local_chain::{CheckPoint, LocalChain},
+    indexed_tx_graph::{self, IndexedTxGraph},
+    keychain,
+    local_chain::{self, CheckPoint, LocalChain},
     Append, ConfirmationTimeAnchor,
 };
 
@@ -23,6 +23,11 @@ use example_cli::{
 const DB_MAGIC: &[u8] = b"bdk_example_esplora";
 const DB_PATH: &str = ".bdk_esplora_example.db";
 
+type ChangeSet = (
+    local_chain::ChangeSet,
+    indexed_tx_graph::ChangeSet<ConfirmationTimeAnchor, keychain::ChangeSet<Keychain>>,
+);
+
 #[derive(Subcommand, Debug, Clone)]
 enum EsploraCommands {
     /// Scans the addresses in the wallet using the esplora API.
@@ -60,22 +65,22 @@ pub struct ScanOptions {
 }
 
 fn main() -> anyhow::Result<()> {
-    let (args, keymap, index, db, init_changeset) = example_cli::init::<
-        EsploraCommands,
-        WalletChangeSet<Keychain, ConfirmationTimeAnchor>,
-    >(DB_MAGIC, DB_PATH)?;
+    let (args, keymap, index, db, init_changeset) =
+        example_cli::init::<EsploraCommands, ChangeSet>(DB_MAGIC, DB_PATH)?;
+
+    let (init_chain_changeset, init_indexed_tx_graph_changeset) = init_changeset;
 
     // Contruct `IndexedTxGraph` and `LocalChain` with our initial changeset. They are wrapped in
     // `Mutex` to display how they can be used in a multithreaded context. Technically the mutexes
     // aren't strictly needed here.
     let graph = Mutex::new({
         let mut graph = IndexedTxGraph::new(index);
-        graph.apply_changeset(init_changeset.indexed_tx_graph);
+        graph.apply_changeset(init_indexed_tx_graph_changeset);
         graph
     });
     let chain = Mutex::new({
         let mut chain = LocalChain::default();
-        chain.apply_changeset(&init_changeset.chain);
+        chain.apply_changeset(&init_chain_changeset);
         chain
     });
 
@@ -307,18 +312,17 @@ fn main() -> anyhow::Result<()> {
     println!("missing block heights: {:?}", missing_block_heights);
 
     // Here, we actually fetch the missing blocks and create a `local_chain::Update`.
-    let chain_update = client
-        .update_local_chain(tip, missing_block_heights)
-        .context("scanning for blocks")?;
-
-    println!("new tip: {}", chain_update.tip.height());
+    let chain_changeset = {
+        let chain_update = client
+            .update_local_chain(tip, missing_block_heights)
+            .context("scanning for blocks")?;
+        println!("new tip: {}", chain_update.tip.height());
+        chain.lock().unwrap().apply_update(chain_update)?
+    };
 
     // We persist the changes
     let mut db = db.lock().unwrap();
-    db.stage(WalletChangeSet {
-        chain: chain.lock().unwrap().apply_update(chain_update)?,
-        indexed_tx_graph: indexed_tx_graph_changeset,
-    });
+    db.stage((chain_changeset, indexed_tx_graph_changeset));
     db.commit()?;
     Ok(())
 }