Skip to content

Commit 9e681b3

Browse files
Merge #1190: Add Wallet::list_output method
278210b docs(bdk): clarify `insert_txout` docs (志宇) 6fb45d8 test(bdk): add `test_list_output` (志宇) e803ee9 feat(bdk): add `Wallet::list_output` method (志宇) 8263289 refactor(bdk)!: rename `LocalUtxo` to `LocalOutput` (志宇) Pull request description: Fixes #1184 ### Description Introduce `Wallet::list_output` method that lists all outputs (both spent and unspent) in a consistent history. ### Changelog notice - Rename `LocalUtxo` to `LocalOutput`. - Add `Wallet::list_output` method. ### Checklists #### All Submissions: * [x] I've signed all my commits * [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md) * [x] I ran `cargo fmt` and `cargo clippy` before committing #### New Features: * [x] I've added tests for the new feature * [x] I've added docs for the new feature ACKs for top commit: notmandatory: re-ACK 278210b danielabrozzoni: ACK 278210b Tree-SHA512: 151af0e05e55d9c682271ef0c7a82e189531db963f65aa62c2ba0507f203dde39ab7561521c56e72c26830828e94ff96b7bd7e3f46082b23f79c5e0f89470136
2 parents 73862be + 278210b commit 9e681b3

File tree

6 files changed

+60
-22
lines changed

6 files changed

+60
-22
lines changed

crates/bdk/src/types.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ impl Vbytes for usize {
161161
///
162162
/// [`Wallet`]: crate::Wallet
163163
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash)]
164-
pub struct LocalUtxo {
164+
pub struct LocalOutput {
165165
/// Reference to a transaction output
166166
pub outpoint: OutPoint,
167167
/// Transaction output
@@ -192,7 +192,7 @@ pub struct WeightedUtxo {
192192
/// An unspent transaction output (UTXO).
193193
pub enum Utxo {
194194
/// A UTXO owned by the local wallet.
195-
Local(LocalUtxo),
195+
Local(LocalOutput),
196196
/// A UTXO owned by another wallet.
197197
Foreign {
198198
/// The location of the output.

crates/bdk/src/wallet/coin_selection.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,7 @@ mod test {
742742
.unwrap();
743743
WeightedUtxo {
744744
satisfaction_weight: P2WPKH_SATISFACTION_SIZE,
745-
utxo: Utxo::Local(LocalUtxo {
745+
utxo: Utxo::Local(LocalOutput {
746746
outpoint,
747747
txout: TxOut {
748748
value,
@@ -802,7 +802,7 @@ mod test {
802802
for _ in 0..utxos_number {
803803
res.push(WeightedUtxo {
804804
satisfaction_weight: P2WPKH_SATISFACTION_SIZE,
805-
utxo: Utxo::Local(LocalUtxo {
805+
utxo: Utxo::Local(LocalOutput {
806806
outpoint: OutPoint::from_str(
807807
"ebd9813ecebc57ff8f30797de7c205e3c7498ca950ea4341ee51a685ff2fa30a:0",
808808
)
@@ -831,7 +831,7 @@ mod test {
831831
fn generate_same_value_utxos(utxos_value: u64, utxos_number: usize) -> Vec<WeightedUtxo> {
832832
let utxo = WeightedUtxo {
833833
satisfaction_weight: P2WPKH_SATISFACTION_SIZE,
834-
utxo: Utxo::Local(LocalUtxo {
834+
utxo: Utxo::Local(LocalOutput {
835835
outpoint: OutPoint::from_str(
836836
"ebd9813ecebc57ff8f30797de7c205e3c7498ca950ea4341ee51a685ff2fa30a:0",
837837
)

crates/bdk/src/wallet/mod.rs

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -735,7 +735,7 @@ impl<D> Wallet<D> {
735735
}
736736

737737
/// Return the list of unspent outputs of this wallet
738-
pub fn list_unspent(&self) -> impl Iterator<Item = LocalUtxo> + '_ {
738+
pub fn list_unspent(&self) -> impl Iterator<Item = LocalOutput> + '_ {
739739
self.indexed_graph
740740
.graph()
741741
.filter_chain_unspents(
@@ -746,6 +746,20 @@ impl<D> Wallet<D> {
746746
.map(|((k, i), full_txo)| new_local_utxo(k, i, full_txo))
747747
}
748748

749+
/// List all relevant outputs (includes both spent and unspent, confirmed and unconfirmed).
750+
///
751+
/// To list only unspent outputs (UTXOs), use [`Wallet::list_unspent`] instead.
752+
pub fn list_output(&self) -> impl Iterator<Item = LocalOutput> + '_ {
753+
self.indexed_graph
754+
.graph()
755+
.filter_chain_txouts(
756+
&self.chain,
757+
self.chain.tip().block_id(),
758+
self.indexed_graph.index.outpoints().iter().cloned(),
759+
)
760+
.map(|((k, i), full_txo)| new_local_utxo(k, i, full_txo))
761+
}
762+
749763
/// Get all the checkpoints the wallet is currently storing indexed by height.
750764
pub fn checkpoints(&self) -> CheckPointIter {
751765
self.chain.iter_checkpoints()
@@ -784,7 +798,7 @@ impl<D> Wallet<D> {
784798

785799
/// Returns the utxo owned by this wallet corresponding to `outpoint` if it exists in the
786800
/// wallet's database.
787-
pub fn get_utxo(&self, op: OutPoint) -> Option<LocalUtxo> {
801+
pub fn get_utxo(&self, op: OutPoint) -> Option<LocalOutput> {
788802
let (&spk_i, _) = self.indexed_graph.index.txout(op)?;
789803
self.indexed_graph
790804
.graph()
@@ -798,15 +812,20 @@ impl<D> Wallet<D> {
798812
}
799813

800814
/// Inserts a [`TxOut`] at [`OutPoint`] into the wallet's transaction graph.
801-
/// Any inserted TxOuts are not persisted until [`commit`] is called.
802815
///
803-
/// This can be used to add a `TxOut` that the wallet doesn't own but is used as an input to
804-
/// a [`Transaction`] passed to the [`calculate_fee`] or [`calculate_fee_rate`] functions.
816+
/// This is used for providing a previous output's value so that we can use [`calculate_fee`]
817+
/// or [`calculate_fee_rate`] on a given transaction. Outputs inserted with this method will
818+
/// not be returned in [`list_unspent`] or [`list_output`].
819+
///
820+
/// Any inserted `TxOut`s are not persisted until [`commit`] is called.
805821
///
806-
/// Only insert TxOuts you trust the values for!
822+
/// **WARNING:** This should only be used to add `TxOut`s that the wallet does not own. Only
823+
/// insert `TxOut`s that you trust the values for!
807824
///
808825
/// [`calculate_fee`]: Self::calculate_fee
809826
/// [`calculate_fee_rate`]: Self::calculate_fee_rate
827+
/// [`list_unspent`]: Self::list_unspent
828+
/// [`list_output`]: Self::list_output
810829
/// [`commit`]: Self::commit
811830
pub fn insert_txout(&mut self, outpoint: OutPoint, txout: TxOut)
812831
where
@@ -1614,7 +1633,7 @@ impl<D> Wallet<D> {
16141633
.max_satisfaction_weight()
16151634
.unwrap();
16161635
WeightedUtxo {
1617-
utxo: Utxo::Local(LocalUtxo {
1636+
utxo: Utxo::Local(LocalOutput {
16181637
outpoint: txin.previous_output,
16191638
txout: txout.clone(),
16201639
keychain,
@@ -1933,7 +1952,7 @@ impl<D> Wallet<D> {
19331952
descriptor.at_derivation_index(child).ok()
19341953
}
19351954

1936-
fn get_available_utxos(&self) -> Vec<(LocalUtxo, usize)> {
1955+
fn get_available_utxos(&self) -> Vec<(LocalOutput, usize)> {
19371956
self.list_unspent()
19381957
.map(|utxo| {
19391958
let keychain = utxo.keychain;
@@ -2130,7 +2149,7 @@ impl<D> Wallet<D> {
21302149
/// get the corresponding PSBT Input for a LocalUtxo
21312150
pub fn get_psbt_input(
21322151
&self,
2133-
utxo: LocalUtxo,
2152+
utxo: LocalOutput,
21342153
sighash_type: Option<psbt::PsbtSighashType>,
21352154
only_witness_utxo: bool,
21362155
) -> Result<psbt::Input, CreateTxError<D::WriteError>>
@@ -2336,8 +2355,8 @@ fn new_local_utxo(
23362355
keychain: KeychainKind,
23372356
derivation_index: u32,
23382357
full_txo: FullTxOut<ConfirmationTimeHeightAnchor>,
2339-
) -> LocalUtxo {
2340-
LocalUtxo {
2358+
) -> LocalOutput {
2359+
LocalOutput {
23412360
outpoint: full_txo.outpoint,
23422361
txout: full_txo.txout,
23432362
is_spent: full_txo.spent_by.is_some(),

crates/bdk/src/wallet/tx_builder.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ use bitcoin::{absolute, script::PushBytes, OutPoint, ScriptBuf, Sequence, Transa
5353

5454
use super::coin_selection::{CoinSelectionAlgorithm, DefaultCoinSelectionAlgorithm};
5555
use super::ChangeSet;
56-
use crate::types::{FeeRate, KeychainKind, LocalUtxo, WeightedUtxo};
56+
use crate::types::{FeeRate, KeychainKind, LocalOutput, WeightedUtxo};
5757
use crate::wallet::CreateTxError;
5858
use crate::{Utxo, Wallet};
5959

@@ -889,7 +889,7 @@ impl Default for ChangeSpendPolicy {
889889
}
890890

891891
impl ChangeSpendPolicy {
892-
pub(crate) fn is_satisfied_by(&self, utxo: &LocalUtxo) -> bool {
892+
pub(crate) fn is_satisfied_by(&self, utxo: &LocalOutput) -> bool {
893893
match self {
894894
ChangeSpendPolicy::ChangeAllowed => true,
895895
ChangeSpendPolicy::OnlyChange => utxo.keychain == KeychainKind::Internal,
@@ -994,11 +994,11 @@ mod test {
994994
);
995995
}
996996

997-
fn get_test_utxos() -> Vec<LocalUtxo> {
997+
fn get_test_utxos() -> Vec<LocalOutput> {
998998
use bitcoin::hashes::Hash;
999999

10001000
vec![
1001-
LocalUtxo {
1001+
LocalOutput {
10021002
outpoint: OutPoint {
10031003
txid: bitcoin::Txid::from_slice(&[0; 32]).unwrap(),
10041004
vout: 0,
@@ -1009,7 +1009,7 @@ mod test {
10091009
confirmation_time: ConfirmationTime::Unconfirmed { last_seen: 0 },
10101010
derivation_index: 0,
10111011
},
1012-
LocalUtxo {
1012+
LocalOutput {
10131013
outpoint: OutPoint {
10141014
txid: bitcoin::Txid::from_slice(&[0; 32]).unwrap(),
10151015
vout: 1,

crates/bdk/tests/common.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#![allow(unused)]
22

3-
use bdk::{wallet::AddressIndex, KeychainKind, LocalUtxo, Wallet};
3+
use bdk::{wallet::AddressIndex, KeychainKind, LocalOutput, Wallet};
44
use bdk_chain::indexed_tx_graph::Indexer;
55
use bdk_chain::{BlockId, ConfirmationTime};
66
use bitcoin::hashes::Hash;

crates/bdk/tests/wallet.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,25 @@ fn test_get_funded_wallet_tx_fee_rate() {
237237
assert_eq!(tx_fee_rate.as_sat_per_vb(), 8.849558);
238238
}
239239

240+
#[test]
241+
fn test_list_output() {
242+
let (wallet, txid) = get_funded_wallet(get_test_wpkh());
243+
let txos = wallet
244+
.list_output()
245+
.map(|op| (op.outpoint, op))
246+
.collect::<std::collections::BTreeMap<_, _>>();
247+
assert_eq!(txos.len(), 2);
248+
for (op, txo) in txos {
249+
if op.txid == txid {
250+
assert_eq!(txo.txout.value, 50_000);
251+
assert!(!txo.is_spent);
252+
} else {
253+
assert_eq!(txo.txout.value, 76_000);
254+
assert!(txo.is_spent);
255+
}
256+
}
257+
}
258+
240259
macro_rules! assert_fee_rate {
241260
($psbt:expr, $fees:expr, $fee_rate:expr $( ,@dust_change $( $dust_change:expr )* )* $( ,@add_signature $( $add_signature:expr )* )* ) => ({
242261
let psbt = $psbt.clone();

0 commit comments

Comments
 (0)