• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

bitcoindevkit / bdk / 9519613010

14 Jun 2024 04:52PM UTC coverage: 83.312% (+0.2%) from 83.064%
9519613010

Pull #1473

github

web-flow
Merge feb27df18 into bc420923c
Pull Request #1473: Remove `persist` submodule

58 of 64 new or added lines in 5 files covered. (90.63%)

1 existing line in 1 file now uncovered.

11128 of 13357 relevant lines covered (83.31%)

17626.96 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

16.28
/crates/wallet/src/wallet/error.rs
1
// Bitcoin Dev Kit
2
// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
3
//
4
// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
5
//
6
// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
7
// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
8
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
9
// You may not use this file except in accordance with one or both of these
10
// licenses.
11

12
//! Errors that can be thrown by the [`Wallet`](crate::wallet::Wallet)
13

14
use crate::descriptor::policy::PolicyError;
15
use crate::descriptor::DescriptorError;
16
use crate::wallet::coin_selection;
17
use crate::{descriptor, KeychainKind};
18
use alloc::string::String;
19
use bitcoin::{absolute, psbt, Amount, OutPoint, Sequence, Txid};
20
use core::fmt;
21

22
/// Errors returned by miniscript when updating inconsistent PSBTs
23
#[derive(Debug, Clone)]
24
pub enum MiniscriptPsbtError {
25
    /// Descriptor key conversion error
26
    Conversion(miniscript::descriptor::ConversionError),
27
    /// Return error type for PsbtExt::update_input_with_descriptor
28
    UtxoUpdate(miniscript::psbt::UtxoUpdateError),
29
    /// Return error type for PsbtExt::update_output_with_descriptor
30
    OutputUpdate(miniscript::psbt::OutputUpdateError),
31
}
32

33
impl fmt::Display for MiniscriptPsbtError {
34
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
×
35
        match self {
×
36
            Self::Conversion(err) => write!(f, "Conversion error: {}", err),
×
37
            Self::UtxoUpdate(err) => write!(f, "UTXO update error: {}", err),
×
38
            Self::OutputUpdate(err) => write!(f, "Output update error: {}", err),
×
39
        }
40
    }
×
41
}
42

43
#[cfg(feature = "std")]
44
impl std::error::Error for MiniscriptPsbtError {}
45

46
#[derive(Debug)]
47
/// Error returned from [`TxBuilder::finish`]
48
///
49
/// [`TxBuilder::finish`]: crate::wallet::tx_builder::TxBuilder::finish
50
pub enum CreateTxError {
51
    /// There was a problem with the descriptors passed in
52
    Descriptor(DescriptorError),
53
    /// There was a problem while extracting and manipulating policies
54
    Policy(PolicyError),
55
    /// Spending policy is not compatible with this [`KeychainKind`]
56
    SpendingPolicyRequired(KeychainKind),
57
    /// Requested invalid transaction version '0'
58
    Version0,
59
    /// Requested transaction version `1`, but at least `2` is needed to use OP_CSV
60
    Version1Csv,
61
    /// Requested `LockTime` is less than is required to spend from this script
62
    LockTime {
63
        /// Requested `LockTime`
64
        requested: absolute::LockTime,
65
        /// Required `LockTime`
66
        required: absolute::LockTime,
67
    },
68
    /// Cannot enable RBF with a `Sequence` >= 0xFFFFFFFE
69
    RbfSequence,
70
    /// Cannot enable RBF with `Sequence` given a required OP_CSV
71
    RbfSequenceCsv {
72
        /// Given RBF `Sequence`
73
        rbf: Sequence,
74
        /// Required OP_CSV `Sequence`
75
        csv: Sequence,
76
    },
77
    /// When bumping a tx the absolute fee requested is lower than replaced tx absolute fee
78
    FeeTooLow {
79
        /// Required fee absolute value [`Amount`]
80
        required: Amount,
81
    },
82
    /// When bumping a tx the fee rate requested is lower than required
83
    FeeRateTooLow {
84
        /// Required fee rate
85
        required: bitcoin::FeeRate,
86
    },
87
    /// `manually_selected_only` option is selected but no utxo has been passed
88
    NoUtxosSelected,
89
    /// Output created is under the dust limit, 546 satoshis
90
    OutputBelowDustLimit(usize),
91
    /// There was an error with coin selection
92
    CoinSelection(coin_selection::Error),
93
    /// Cannot build a tx without recipients
94
    NoRecipients,
95
    /// Partially signed bitcoin transaction error
96
    Psbt(psbt::Error),
97
    /// In order to use the [`TxBuilder::add_global_xpubs`] option every extended
98
    /// key in the descriptor must either be a master key itself (having depth = 0) or have an
99
    /// explicit origin provided
100
    ///
101
    /// [`TxBuilder::add_global_xpubs`]: crate::wallet::tx_builder::TxBuilder::add_global_xpubs
102
    MissingKeyOrigin(String),
103
    /// Happens when trying to spend an UTXO that is not in the internal database
104
    UnknownUtxo,
105
    /// Missing non_witness_utxo on foreign utxo for given `OutPoint`
106
    MissingNonWitnessUtxo(OutPoint),
107
    /// Miniscript PSBT error
108
    MiniscriptPsbt(MiniscriptPsbtError),
109
}
110

111
impl fmt::Display for CreateTxError {
112
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
8✔
113
        match self {
8✔
114
            Self::Descriptor(e) => e.fmt(f),
×
115
            Self::Policy(e) => e.fmt(f),
×
116
            CreateTxError::SpendingPolicyRequired(keychain_kind) => {
×
117
                write!(f, "Spending policy required: {:?}", keychain_kind)
×
118
            }
119
            CreateTxError::Version0 => {
120
                write!(f, "Invalid version `0`")
×
121
            }
122
            CreateTxError::Version1Csv => {
123
                write!(
×
124
                    f,
×
125
                    "TxBuilder requested version `1`, but at least `2` is needed to use OP_CSV"
×
126
                )
×
127
            }
128
            CreateTxError::LockTime {
129
                requested,
×
130
                required,
×
131
            } => {
×
132
                write!(f, "TxBuilder requested timelock of `{:?}`, but at least `{:?}` is required to spend from this script", required, requested)
×
133
            }
134
            CreateTxError::RbfSequence => {
135
                write!(f, "Cannot enable RBF with a nSequence >= 0xFFFFFFFE")
×
136
            }
137
            CreateTxError::RbfSequenceCsv { rbf, csv } => {
×
138
                write!(
×
139
                    f,
×
140
                    "Cannot enable RBF with nSequence `{:?}` given a required OP_CSV of `{:?}`",
×
141
                    rbf, csv
×
142
                )
×
143
            }
144
            CreateTxError::FeeTooLow { required } => {
×
145
                write!(f, "Fee to low: required {}", required.display_dynamic())
×
146
            }
147
            CreateTxError::FeeRateTooLow { required } => {
8✔
148
                write!(
8✔
149
                    f,
8✔
150
                    // Note: alternate fmt as sat/vb (ceil) available in bitcoin-0.31
8✔
151
                    //"Fee rate too low: required {required:#}"
8✔
152
                    "Fee rate too low: required {} sat/vb",
8✔
153
                    crate::floating_rate!(required)
8✔
154
                )
8✔
155
            }
156
            CreateTxError::NoUtxosSelected => {
157
                write!(f, "No UTXO selected")
×
158
            }
159
            CreateTxError::OutputBelowDustLimit(limit) => {
×
160
                write!(f, "Output below the dust limit: {}", limit)
×
161
            }
162
            CreateTxError::CoinSelection(e) => e.fmt(f),
×
163
            CreateTxError::NoRecipients => {
164
                write!(f, "Cannot build tx without recipients")
×
165
            }
166
            CreateTxError::Psbt(e) => e.fmt(f),
×
167
            CreateTxError::MissingKeyOrigin(err) => {
×
168
                write!(f, "Missing key origin: {}", err)
×
169
            }
170
            CreateTxError::UnknownUtxo => {
171
                write!(f, "UTXO not found in the internal database")
×
172
            }
173
            CreateTxError::MissingNonWitnessUtxo(outpoint) => {
×
174
                write!(f, "Missing non_witness_utxo on foreign utxo {}", outpoint)
×
175
            }
176
            CreateTxError::MiniscriptPsbt(err) => {
×
177
                write!(f, "Miniscript PSBT error: {}", err)
×
178
            }
179
        }
180
    }
8✔
181
}
182

183
impl From<descriptor::error::Error> for CreateTxError {
184
    fn from(err: descriptor::error::Error) -> Self {
×
185
        CreateTxError::Descriptor(err)
×
186
    }
×
187
}
188

189
impl From<PolicyError> for CreateTxError {
190
    fn from(err: PolicyError) -> Self {
×
191
        CreateTxError::Policy(err)
×
192
    }
×
193
}
194

195
impl From<MiniscriptPsbtError> for CreateTxError {
196
    fn from(err: MiniscriptPsbtError) -> Self {
×
197
        CreateTxError::MiniscriptPsbt(err)
×
198
    }
×
199
}
200

201
impl From<psbt::Error> for CreateTxError {
202
    fn from(err: psbt::Error) -> Self {
×
203
        CreateTxError::Psbt(err)
×
204
    }
×
205
}
206

207
impl From<coin_selection::Error> for CreateTxError {
208
    fn from(err: coin_selection::Error) -> Self {
56✔
209
        CreateTxError::CoinSelection(err)
56✔
210
    }
56✔
211
}
212

213
#[cfg(feature = "std")]
214
impl std::error::Error for CreateTxError {}
215

216
#[derive(Debug)]
217
/// Error returned from [`Wallet::build_fee_bump`]
218
///
219
/// [`Wallet::build_fee_bump`]: super::Wallet::build_fee_bump
220
pub enum BuildFeeBumpError {
221
    /// Happens when trying to spend an UTXO that is not in the internal database
222
    UnknownUtxo(OutPoint),
223
    /// Thrown when a tx is not found in the internal database
224
    TransactionNotFound(Txid),
225
    /// Happens when trying to bump a transaction that is already confirmed
226
    TransactionConfirmed(Txid),
227
    /// Trying to replace a tx that has a sequence >= `0xFFFFFFFE`
228
    IrreplaceableTransaction(Txid),
229
    /// Node doesn't have data to estimate a fee rate
230
    FeeRateUnavailable,
231
}
232

233
impl fmt::Display for BuildFeeBumpError {
234
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
×
235
        match self {
×
236
            Self::UnknownUtxo(outpoint) => write!(
×
237
                f,
×
238
                "UTXO not found in the internal database with txid: {}, vout: {}",
×
239
                outpoint.txid, outpoint.vout
×
240
            ),
×
241
            Self::TransactionNotFound(txid) => {
×
242
                write!(
×
243
                    f,
×
244
                    "Transaction not found in the internal database with txid: {}",
×
245
                    txid
×
246
                )
×
247
            }
248
            Self::TransactionConfirmed(txid) => {
×
249
                write!(f, "Transaction already confirmed with txid: {}", txid)
×
250
            }
251
            Self::IrreplaceableTransaction(txid) => {
×
252
                write!(f, "Transaction can't be replaced with txid: {}", txid)
×
253
            }
254
            Self::FeeRateUnavailable => write!(f, "Fee rate unavailable"),
×
255
        }
256
    }
×
257
}
258

259
#[cfg(feature = "std")]
260
impl std::error::Error for BuildFeeBumpError {}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc