Skip to content

Commit 3135e29

Browse files
committed
test(wallet): add helpers to test_utils
1 parent 823bb39 commit 3135e29

File tree

2 files changed

+102
-71
lines changed

2 files changed

+102
-71
lines changed

crates/wallet/src/test_utils.rs

Lines changed: 101 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
//! `bdk_wallet` test utilities
22
33
use alloc::string::ToString;
4+
use alloc::sync::Arc;
45
use core::str::FromStr;
56

6-
use bdk_chain::{tx_graph, BlockId, ConfirmationBlockTime};
7+
use bdk_chain::{tx_graph, BlockId, ChainPosition, ConfirmationBlockTime};
78
use bitcoin::{
8-
hashes::Hash, transaction, Address, Amount, BlockHash, FeeRate, Network, OutPoint, Transaction,
9-
TxIn, TxOut, Txid,
9+
absolute, hashes::Hash, transaction, Address, Amount, BlockHash, FeeRate, Network, OutPoint,
10+
Transaction, TxIn, TxOut, Txid,
1011
};
1112

1213
use crate::{KeychainKind, Update, Wallet};
@@ -224,6 +225,90 @@ pub fn feerate_unchecked(sat_vb: f64) -> FeeRate {
224225
FeeRate::from_sat_per_kwu(sat_kwu)
225226
}
226227

228+
/// Receive a tx output with the given value in the latest block
229+
pub fn receive_output_in_latest_block(wallet: &mut Wallet, value: u64) -> OutPoint {
230+
let latest_cp = wallet.latest_checkpoint();
231+
let height = latest_cp.height();
232+
let anchor = if height == 0 {
233+
ChainPosition::Unconfirmed(0)
234+
} else {
235+
ChainPosition::Confirmed(ConfirmationBlockTime {
236+
block_id: latest_cp.block_id(),
237+
confirmation_time: 0,
238+
})
239+
};
240+
receive_output(wallet, value, anchor)
241+
}
242+
243+
/// Receive a tx output with the given value and chain position
244+
pub fn receive_output(
245+
wallet: &mut Wallet,
246+
value: u64,
247+
pos: ChainPosition<ConfirmationBlockTime>,
248+
) -> OutPoint {
249+
let addr = wallet.next_unused_address(KeychainKind::External).address;
250+
receive_output_to_address(wallet, addr, value, pos)
251+
}
252+
253+
/// Receive a tx output to an address with the given value and chain position
254+
pub fn receive_output_to_address(
255+
wallet: &mut Wallet,
256+
addr: Address,
257+
value: u64,
258+
pos: ChainPosition<ConfirmationBlockTime>,
259+
) -> OutPoint {
260+
let tx = Transaction {
261+
version: transaction::Version::ONE,
262+
lock_time: absolute::LockTime::ZERO,
263+
input: vec![],
264+
output: vec![TxOut {
265+
script_pubkey: addr.script_pubkey(),
266+
value: Amount::from_sat(value),
267+
}],
268+
};
269+
270+
let txid = tx.compute_txid();
271+
wallet.insert_tx(tx);
272+
273+
match pos {
274+
ChainPosition::Confirmed(anchor) => {
275+
insert_anchor(wallet, txid, anchor);
276+
}
277+
ChainPosition::Unconfirmed(last_seen) => {
278+
insert_seen_at(wallet, txid, last_seen);
279+
}
280+
}
281+
282+
OutPoint { txid, vout: 0 }
283+
}
284+
285+
/// Insert a checkpoint into the wallet. This can be used to extend the wallet's local chain
286+
/// or to insert a block that did not exist previously. Note that if replacing a block with
287+
/// a different one at the same height, then all later blocks are evicted as well.
288+
pub fn insert_checkpoint(wallet: &mut Wallet, block: BlockId) {
289+
let mut cp = wallet.latest_checkpoint();
290+
cp = cp.insert(block);
291+
wallet
292+
.apply_update(Update {
293+
chain: Some(cp),
294+
..Default::default()
295+
})
296+
.unwrap();
297+
}
298+
299+
/// Insert transaction
300+
pub fn insert_tx(wallet: &mut Wallet, tx: Transaction) {
301+
wallet
302+
.apply_update(Update {
303+
tx_update: bdk_chain::TxUpdate {
304+
txs: vec![Arc::new(tx)],
305+
..Default::default()
306+
},
307+
..Default::default()
308+
})
309+
.unwrap();
310+
}
311+
227312
/// Simulates confirming a tx with `txid` by applying an update to the wallet containing
228313
/// the given `anchor`. Note: to be considered confirmed the anchor block must exist in
229314
/// the current active chain.
@@ -238,3 +323,16 @@ pub fn insert_anchor(wallet: &mut Wallet, txid: Txid, anchor: ConfirmationBlockT
238323
})
239324
.unwrap();
240325
}
326+
327+
/// Marks the given `txid` seen as unconfirmed at `seen_at`
328+
pub fn insert_seen_at(wallet: &mut Wallet, txid: Txid, seen_at: u64) {
329+
wallet
330+
.apply_update(crate::Update {
331+
tx_update: tx_graph::TxUpdate {
332+
seen_ats: [(txid, seen_at)].into_iter().collect(),
333+
..Default::default()
334+
},
335+
..Default::default()
336+
})
337+
.unwrap();
338+
}

crates/wallet/tests/wallet.rs

Lines changed: 1 addition & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use std::str::FromStr;
55

66
use anyhow::Context;
77
use assert_matches::assert_matches;
8-
use bdk_chain::{tx_graph, COINBASE_MATURITY};
8+
use bdk_chain::COINBASE_MATURITY;
99
use bdk_chain::{BlockId, ChainPosition, ConfirmationBlockTime};
1010
use bdk_wallet::coin_selection::{self, LargestFirstCoinSelection};
1111
use bdk_wallet::descriptor::{calc_checksum, DescriptorError, IntoWalletDescriptor};
@@ -31,73 +31,6 @@ use miniscript::{descriptor::KeyMap, Descriptor, DescriptorPublicKey};
3131
use rand::rngs::StdRng;
3232
use rand::SeedableRng;
3333

34-
fn receive_output(
35-
wallet: &mut Wallet,
36-
value: u64,
37-
height: ChainPosition<ConfirmationBlockTime>,
38-
) -> OutPoint {
39-
let addr = wallet.next_unused_address(KeychainKind::External).address;
40-
receive_output_to_address(wallet, addr, value, height)
41-
}
42-
43-
fn receive_output_to_address(
44-
wallet: &mut Wallet,
45-
addr: Address,
46-
value: u64,
47-
height: ChainPosition<ConfirmationBlockTime>,
48-
) -> OutPoint {
49-
let tx = Transaction {
50-
version: transaction::Version::ONE,
51-
lock_time: absolute::LockTime::ZERO,
52-
input: vec![],
53-
output: vec![TxOut {
54-
script_pubkey: addr.script_pubkey(),
55-
value: Amount::from_sat(value),
56-
}],
57-
};
58-
59-
let txid = tx.compute_txid();
60-
wallet.insert_tx(tx);
61-
62-
match height {
63-
ChainPosition::Confirmed(anchor) => {
64-
insert_anchor(wallet, txid, anchor);
65-
}
66-
ChainPosition::Unconfirmed(last_seen) => {
67-
insert_seen_at(wallet, txid, last_seen);
68-
}
69-
}
70-
71-
OutPoint { txid, vout: 0 }
72-
}
73-
74-
fn receive_output_in_latest_block(wallet: &mut Wallet, value: u64) -> OutPoint {
75-
let latest_cp = wallet.latest_checkpoint();
76-
let height = latest_cp.height();
77-
let anchor = if height == 0 {
78-
ChainPosition::Unconfirmed(0)
79-
} else {
80-
ChainPosition::Confirmed(ConfirmationBlockTime {
81-
block_id: latest_cp.block_id(),
82-
confirmation_time: 0,
83-
})
84-
};
85-
receive_output(wallet, value, anchor)
86-
}
87-
88-
fn insert_seen_at(wallet: &mut Wallet, txid: Txid, seen_at: u64) {
89-
use bdk_wallet::Update;
90-
wallet
91-
.apply_update(Update {
92-
tx_update: tx_graph::TxUpdate {
93-
seen_ats: [(txid, seen_at)].into_iter().collect(),
94-
..Default::default()
95-
},
96-
..Default::default()
97-
})
98-
.unwrap();
99-
}
100-
10134
fn parse_descriptor(s: &str) -> (Descriptor<DescriptorPublicKey>, KeyMap) {
10235
<Descriptor<DescriptorPublicKey>>::parse_descriptor(&Secp256k1::new(), s)
10336
.expect("failed to parse descriptor")

0 commit comments

Comments
 (0)