Skip to content

Commit 68572bf

Browse files
vladimirfomeneevanlinjin
authored andcommitted
refactor: move WalletChangeset to wallet module
Consequently, remove the `WalletChangeset` dependency from `example_electrum` and `example_esplora` examples.
1 parent 2392e50 commit 68572bf

File tree

5 files changed

+98
-93
lines changed

5 files changed

+98
-93
lines changed

crates/bdk/src/wallet/mod.rs

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ use alloc::{
2222
pub use bdk_chain::keychain::Balance;
2323
use bdk_chain::{
2424
indexed_tx_graph,
25-
keychain::{KeychainTxOutIndex, WalletChangeSet},
25+
keychain::{self, KeychainTxOutIndex},
2626
local_chain::{self, CannotConnectError, CheckPoint, CheckPointIter, LocalChain},
2727
tx_graph::{CanonicalTx, TxGraph},
28-
Append, BlockId, ChainPosition, ConfirmationTime, ConfirmationTimeAnchor, FullTxOut,
28+
Anchor, Append, BlockId, ChainPosition, ConfirmationTime, ConfirmationTimeAnchor, FullTxOut,
2929
IndexedTxGraph, Persist, PersistBackend,
3030
};
3131
use bitcoin::consensus::encode::serialize;
@@ -124,6 +124,62 @@ impl<K, A> WalletUpdate<K, A> {
124124
}
125125
}
126126

127+
/// A structure that records the corresponding changes as result of applying an [`WalletUpdate`].
128+
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
129+
pub struct WalletChangeSet<K, A> {
130+
/// Changes to the [`LocalChain`].
131+
///
132+
/// [`LocalChain`]: local_chain::LocalChain
133+
pub chain: local_chain::ChangeSet,
134+
135+
/// ChangeSet to [`IndexedTxGraph`].
136+
///
137+
/// [`IndexedTxGraph`]: bdk_chain::indexed_tx_graph::IndexedTxGraph
138+
#[serde(bound(
139+
deserialize = "K: Ord + serde::Deserialize<'de>, A: Ord + serde::Deserialize<'de>",
140+
serialize = "K: Ord + serde::Serialize, A: Ord + serde::Serialize",
141+
))]
142+
pub index_tx_graph: indexed_tx_graph::ChangeSet<A, keychain::ChangeSet<K>>,
143+
}
144+
145+
impl<K, A> Default for WalletChangeSet<K, A> {
146+
fn default() -> Self {
147+
Self {
148+
chain: Default::default(),
149+
index_tx_graph: Default::default(),
150+
}
151+
}
152+
}
153+
154+
impl<K: Ord, A: Anchor> Append for WalletChangeSet<K, A> {
155+
fn append(&mut self, other: Self) {
156+
Append::append(&mut self.chain, other.chain);
157+
Append::append(&mut self.index_tx_graph, other.index_tx_graph);
158+
}
159+
160+
fn is_empty(&self) -> bool {
161+
self.chain.is_empty() && self.index_tx_graph.is_empty()
162+
}
163+
}
164+
165+
impl<K, A> From<local_chain::ChangeSet> for WalletChangeSet<K, A> {
166+
fn from(chain: local_chain::ChangeSet) -> Self {
167+
Self {
168+
chain,
169+
..Default::default()
170+
}
171+
}
172+
}
173+
174+
impl<K, A> From<indexed_tx_graph::ChangeSet<A, keychain::ChangeSet<K>>> for WalletChangeSet<K, A> {
175+
fn from(index_tx_graph: indexed_tx_graph::ChangeSet<A, keychain::ChangeSet<K>>) -> Self {
176+
Self {
177+
index_tx_graph,
178+
..Default::default()
179+
}
180+
}
181+
}
182+
127183
/// The update to a [`Wallet`] used in [`Wallet::apply_update`]. This is usually returned from blockchain data sources.
128184
pub type Update = WalletUpdate<KeychainKind, ConfirmationTimeAnchor>;
129185

@@ -277,7 +333,7 @@ impl<D> Wallet<D> {
277333

278334
let changeset = db.load_from_persistence().map_err(NewError::Persist)?;
279335
chain.apply_changeset(&changeset.chain);
280-
indexed_graph.apply_changeset(changeset.indexed_tx_graph);
336+
indexed_graph.apply_changeset(changeset.index_tx_graph);
281337

282338
let persist = Persist::new(db);
283339

crates/chain/src/keychain.rs

Lines changed: 1 addition & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
//!
1111
//! [`SpkTxOutIndex`]: crate::SpkTxOutIndex
1212
13-
use crate::{collections::BTreeMap, indexed_tx_graph, local_chain, Anchor, Append};
13+
use crate::{collections::BTreeMap, Append};
1414

1515
#[cfg(feature = "miniscript")]
1616
mod txout_index;
@@ -80,69 +80,6 @@ impl<K> AsRef<BTreeMap<K, u32>> for ChangeSet<K> {
8080
}
8181
}
8282

83-
/// A structure that records the corresponding changes as result of applying an [`WalletUpdate`].
84-
#[derive(Debug, Clone, PartialEq)]
85-
#[cfg_attr(
86-
feature = "serde",
87-
derive(serde::Deserialize, serde::Serialize),
88-
serde(
89-
crate = "serde_crate",
90-
bound(
91-
deserialize = "K: Ord + serde::Deserialize<'de>, A: Ord + serde::Deserialize<'de>",
92-
serialize = "K: Ord + serde::Serialize, A: Ord + serde::Serialize",
93-
)
94-
)
95-
)]
96-
pub struct WalletChangeSet<K, A> {
97-
/// Changes to the [`LocalChain`].
98-
///
99-
/// [`LocalChain`]: local_chain::LocalChain
100-
pub chain: local_chain::ChangeSet,
101-
102-
/// ChangeSet to [`IndexedTxGraph`].
103-
///
104-
/// [`IndexedTxGraph`]: crate::indexed_tx_graph::IndexedTxGraph
105-
pub indexed_tx_graph: indexed_tx_graph::ChangeSet<A, ChangeSet<K>>,
106-
}
107-
108-
impl<K, A> Default for WalletChangeSet<K, A> {
109-
fn default() -> Self {
110-
Self {
111-
chain: Default::default(),
112-
indexed_tx_graph: Default::default(),
113-
}
114-
}
115-
}
116-
117-
impl<K: Ord, A: Anchor> Append for WalletChangeSet<K, A> {
118-
fn append(&mut self, other: Self) {
119-
Append::append(&mut self.chain, other.chain);
120-
Append::append(&mut self.indexed_tx_graph, other.indexed_tx_graph);
121-
}
122-
123-
fn is_empty(&self) -> bool {
124-
self.chain.is_empty() && self.indexed_tx_graph.is_empty()
125-
}
126-
}
127-
128-
impl<K, A> From<local_chain::ChangeSet> for WalletChangeSet<K, A> {
129-
fn from(chain: local_chain::ChangeSet) -> Self {
130-
Self {
131-
chain,
132-
..Default::default()
133-
}
134-
}
135-
}
136-
137-
impl<K, A> From<indexed_tx_graph::ChangeSet<A, ChangeSet<K>>> for WalletChangeSet<K, A> {
138-
fn from(indexed_tx_graph: indexed_tx_graph::ChangeSet<A, ChangeSet<K>>) -> Self {
139-
Self {
140-
indexed_tx_graph,
141-
..Default::default()
142-
}
143-
}
144-
}
145-
14683
/// Balance, differentiated into various categories.
14784
#[derive(Debug, PartialEq, Eq, Clone, Default)]
14885
#[cfg_attr(

crates/chain/src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,11 @@ pub mod collections {
100100

101101
/// How many confirmations are needed f or a coinbase output to be spent.
102102
pub const COINBASE_MATURITY: u32 = 100;
103+
104+
impl<A, IA> From<indexed_tx_graph::ChangeSet<A, IA>>
105+
for (local_chain::ChangeSet, indexed_tx_graph::ChangeSet<A, IA>)
106+
{
107+
fn from(indexed_changeset: indexed_tx_graph::ChangeSet<A, IA>) -> Self {
108+
(local_chain::ChangeSet::default(), indexed_changeset)
109+
}
110+
}

example-crates/example_electrum/src/main.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::{
77
use bdk_chain::{
88
bitcoin::{Address, Network, OutPoint, ScriptBuf, Txid},
99
indexed_tx_graph::{self, IndexedTxGraph},
10-
keychain::WalletChangeSet,
10+
keychain,
1111
local_chain::{self, LocalChain},
1212
Append, ConfirmationHeightAnchor,
1313
};
@@ -60,19 +60,22 @@ pub struct ScanOptions {
6060
pub batch_size: usize,
6161
}
6262

63-
type ChangeSet = WalletChangeSet<Keychain, ConfirmationHeightAnchor>;
63+
type ChangeSet = (
64+
local_chain::ChangeSet,
65+
indexed_tx_graph::ChangeSet<ConfirmationHeightAnchor, keychain::ChangeSet<Keychain>>,
66+
);
6467

6568
fn main() -> anyhow::Result<()> {
6669
let (args, keymap, index, db, init_changeset) =
6770
example_cli::init::<ElectrumCommands, ChangeSet>(DB_MAGIC, DB_PATH)?;
6871

6972
let graph = Mutex::new({
7073
let mut graph = IndexedTxGraph::new(index);
71-
graph.apply_changeset(init_changeset.indexed_tx_graph);
74+
graph.apply_changeset(init_changeset.1);
7275
graph
7376
});
7477

75-
let chain = Mutex::new(LocalChain::from_changeset(init_changeset.chain));
78+
let chain = Mutex::new(LocalChain::from_changeset(init_changeset.0));
7679

7780
let electrum_url = match args.network {
7881
Network::Bitcoin => "ssl://electrum.blockstream.info:50002",
@@ -293,10 +296,7 @@ fn main() -> anyhow::Result<()> {
293296
changeset
294297
};
295298

296-
ChangeSet {
297-
indexed_tx_graph,
298-
chain,
299-
}
299+
(chain, indexed_tx_graph)
300300
};
301301

302302
let mut db = db.lock().unwrap();

example-crates/example_esplora/src/main.rs

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ use std::{
66

77
use bdk_chain::{
88
bitcoin::{Address, Network, OutPoint, ScriptBuf, Txid},
9-
indexed_tx_graph::IndexedTxGraph,
10-
keychain::WalletChangeSet,
11-
local_chain::{CheckPoint, LocalChain},
9+
indexed_tx_graph::{self, IndexedTxGraph},
10+
keychain,
11+
local_chain::{self, CheckPoint, LocalChain},
1212
Append, ConfirmationTimeAnchor,
1313
};
1414

@@ -23,6 +23,11 @@ use example_cli::{
2323
const DB_MAGIC: &[u8] = b"bdk_example_esplora";
2424
const DB_PATH: &str = ".bdk_esplora_example.db";
2525

26+
type ChangeSet = (
27+
local_chain::ChangeSet,
28+
indexed_tx_graph::ChangeSet<ConfirmationTimeAnchor, keychain::ChangeSet<Keychain>>,
29+
);
30+
2631
#[derive(Subcommand, Debug, Clone)]
2732
enum EsploraCommands {
2833
/// Scans the addresses in the wallet using the esplora API.
@@ -60,22 +65,22 @@ pub struct ScanOptions {
6065
}
6166

6267
fn main() -> anyhow::Result<()> {
63-
let (args, keymap, index, db, init_changeset) = example_cli::init::<
64-
EsploraCommands,
65-
WalletChangeSet<Keychain, ConfirmationTimeAnchor>,
66-
>(DB_MAGIC, DB_PATH)?;
68+
let (args, keymap, index, db, init_changeset) =
69+
example_cli::init::<EsploraCommands, ChangeSet>(DB_MAGIC, DB_PATH)?;
70+
71+
let (init_chain_changeset, init_indexed_tx_graph_changeset) = init_changeset;
6772

6873
// Contruct `IndexedTxGraph` and `LocalChain` with our initial changeset. They are wrapped in
6974
// `Mutex` to display how they can be used in a multithreaded context. Technically the mutexes
7075
// aren't strictly needed here.
7176
let graph = Mutex::new({
7277
let mut graph = IndexedTxGraph::new(index);
73-
graph.apply_changeset(init_changeset.indexed_tx_graph);
78+
graph.apply_changeset(init_indexed_tx_graph_changeset);
7479
graph
7580
});
7681
let chain = Mutex::new({
7782
let mut chain = LocalChain::default();
78-
chain.apply_changeset(&init_changeset.chain);
83+
chain.apply_changeset(&init_chain_changeset);
7984
chain
8085
});
8186

@@ -307,18 +312,17 @@ fn main() -> anyhow::Result<()> {
307312
println!("missing block heights: {:?}", missing_block_heights);
308313

309314
// Here, we actually fetch the missing blocks and create a `local_chain::Update`.
310-
let chain_update = client
311-
.update_local_chain(tip, missing_block_heights)
312-
.context("scanning for blocks")?;
313-
314-
println!("new tip: {}", chain_update.tip.height());
315+
let chain_changeset = {
316+
let chain_update = client
317+
.update_local_chain(tip, missing_block_heights)
318+
.context("scanning for blocks")?;
319+
println!("new tip: {}", chain_update.tip.height());
320+
chain.lock().unwrap().apply_update(chain_update)?
321+
};
315322

316323
// We persist the changes
317324
let mut db = db.lock().unwrap();
318-
db.stage(WalletChangeSet {
319-
chain: chain.lock().unwrap().apply_update(chain_update)?,
320-
indexed_tx_graph: indexed_tx_graph_changeset,
321-
});
325+
db.stage((chain_changeset, indexed_tx_graph_changeset));
322326
db.commit()?;
323327
Ok(())
324328
}

0 commit comments

Comments
 (0)