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

bitcoindevkit / bdk / 5398026791

pending completion
5398026791

Pull #1002

github

web-flow
Merge 8272aa35d into 26ade1172
Pull Request #1002: Implement linked-list `LocalChain` and add rpc-chain module/example

681 of 681 new or added lines in 9 files covered. (100.0%)

7903 of 10220 relevant lines covered (77.33%)

5078.37 hits per line

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

6.56
/crates/bdk/src/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
use crate::bitcoin::Network;
13
use crate::{descriptor, wallet};
14
use alloc::{string::String, vec::Vec};
15
use bitcoin::{OutPoint, Txid};
16
use core::fmt;
17

18
/// Errors that can be thrown by the [`Wallet`](crate::wallet::Wallet)
19
#[derive(Debug)]
208✔
20
pub enum Error {
21
    /// Generic error
22
    Generic(String),
23
    /// Cannot build a tx without recipients
24
    NoRecipients,
25
    /// `manually_selected_only` option is selected but no utxo has been passed
26
    NoUtxosSelected,
27
    /// Output created is under the dust limit, 546 satoshis
28
    OutputBelowDustLimit(usize),
29
    /// Wallet's UTXO set is not enough to cover recipient's requested plus fee
30
    InsufficientFunds {
31
        /// Sats needed for some transaction
32
        needed: u64,
33
        /// Sats available for spending
34
        available: u64,
35
    },
36
    /// Branch and bound coin selection possible attempts with sufficiently big UTXO set could grow
37
    /// exponentially, thus a limit is set, and when hit, this error is thrown
38
    BnBTotalTriesExceeded,
39
    /// Branch and bound coin selection tries to avoid needing a change by finding the right inputs for
40
    /// the desired outputs plus fee, if there is not such combination this error is thrown
41
    BnBNoExactMatch,
42
    /// Happens when trying to spend an UTXO that is not in the internal database
43
    UnknownUtxo,
44
    /// Thrown when a tx is not found in the internal database
45
    TransactionNotFound,
46
    /// Happens when trying to bump a transaction that is already confirmed
47
    TransactionConfirmed,
48
    /// Trying to replace a tx that has a sequence >= `0xFFFFFFFE`
49
    IrreplaceableTransaction,
50
    /// When bumping a tx the fee rate requested is lower than required
51
    FeeRateTooLow {
52
        /// Required fee rate (satoshi/vbyte)
53
        required: crate::types::FeeRate,
54
    },
55
    /// When bumping a tx the absolute fee requested is lower than replaced tx absolute fee
56
    FeeTooLow {
57
        /// Required fee absolute value (satoshi)
58
        required: u64,
59
    },
60
    /// Node doesn't have data to estimate a fee rate
61
    FeeRateUnavailable,
62
    /// In order to use the [`TxBuilder::add_global_xpubs`] option every extended
63
    /// key in the descriptor must either be a master key itself (having depth = 0) or have an
64
    /// explicit origin provided
65
    ///
66
    /// [`TxBuilder::add_global_xpubs`]: crate::wallet::tx_builder::TxBuilder::add_global_xpubs
67
    MissingKeyOrigin(String),
68
    /// Error while working with [`keys`](crate::keys)
69
    Key(crate::keys::KeyError),
70
    /// Descriptor checksum mismatch
71
    ChecksumMismatch,
72
    /// Spending policy is not compatible with this [`KeychainKind`](crate::types::KeychainKind)
73
    SpendingPolicyRequired(crate::types::KeychainKind),
74
    /// Error while extracting and manipulating policies
75
    InvalidPolicyPathError(crate::descriptor::policy::PolicyError),
76
    /// Signing error
77
    Signer(crate::wallet::signer::SignerError),
78
    /// Requested outpoint doesn't exist in the tx (vout greater than available outputs)
79
    InvalidOutpoint(OutPoint),
80
    /// Error related to the parsing and usage of descriptors
81
    Descriptor(crate::descriptor::error::Error),
82
    /// Miniscript error
83
    Miniscript(miniscript::Error),
84
    /// Miniscript PSBT error
85
    MiniscriptPsbt(MiniscriptPsbtError),
86
    /// BIP32 error
87
    Bip32(bitcoin::util::bip32::Error),
88
    /// Partially signed bitcoin transaction error
89
    Psbt(bitcoin::util::psbt::Error),
90
}
91

92
/// Errors returned by miniscript when updating inconsistent PSBTs
93
#[derive(Debug, Clone)]
×
94
pub enum MiniscriptPsbtError {
95
    Conversion(miniscript::descriptor::ConversionError),
96
    UtxoUpdate(miniscript::psbt::UtxoUpdateError),
97
    OutputUpdate(miniscript::psbt::OutputUpdateError),
98
}
99

100
impl fmt::Display for MiniscriptPsbtError {
101
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
×
102
        match self {
×
103
            Self::Conversion(err) => write!(f, "Conversion error: {}", err),
×
104
            Self::UtxoUpdate(err) => write!(f, "UTXO update error: {}", err),
×
105
            Self::OutputUpdate(err) => write!(f, "Output update error: {}", err),
×
106
        }
107
    }
×
108
}
109

110
#[cfg(feature = "std")]
111
impl std::error::Error for MiniscriptPsbtError {}
112

113
#[cfg(feature = "std")]
114
impl fmt::Display for Error {
115
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
×
116
        match self {
×
117
            Self::Generic(err) => write!(f, "Generic error: {}", err),
×
118
            Self::NoRecipients => write!(f, "Cannot build tx without recipients"),
×
119
            Self::NoUtxosSelected => write!(f, "No UTXO selected"),
×
120
            Self::OutputBelowDustLimit(limit) => {
×
121
                write!(f, "Output below the dust limit: {}", limit)
×
122
            }
123
            Self::InsufficientFunds { needed, available } => write!(
×
124
                f,
×
125
                "Insufficient funds: {} sat available of {} sat needed",
×
126
                available, needed
×
127
            ),
×
128
            Self::BnBTotalTriesExceeded => {
129
                write!(f, "Branch and bound coin selection: total tries exceeded")
×
130
            }
131
            Self::BnBNoExactMatch => write!(f, "Branch and bound coin selection: not exact match"),
×
132
            Self::UnknownUtxo => write!(f, "UTXO not found in the internal database"),
×
133
            Self::TransactionNotFound => {
134
                write!(f, "Transaction not found in the internal database")
×
135
            }
136
            Self::TransactionConfirmed => write!(f, "Transaction already confirmed"),
×
137
            Self::IrreplaceableTransaction => write!(f, "Transaction can't be replaced"),
×
138
            Self::FeeRateTooLow { required } => write!(
×
139
                f,
×
140
                "Fee rate too low: required {} sat/vbyte",
×
141
                required.as_sat_per_vb()
×
142
            ),
×
143
            Self::FeeTooLow { required } => write!(f, "Fee to low: required {} sat", required),
×
144
            Self::FeeRateUnavailable => write!(f, "Fee rate unavailable"),
×
145
            Self::MissingKeyOrigin(err) => write!(f, "Missing key origin: {}", err),
×
146
            Self::Key(err) => write!(f, "Key error: {}", err),
×
147
            Self::ChecksumMismatch => write!(f, "Descriptor checksum mismatch"),
×
148
            Self::SpendingPolicyRequired(keychain_kind) => {
×
149
                write!(f, "Spending policy required: {:?}", keychain_kind)
×
150
            }
151
            Self::InvalidPolicyPathError(err) => write!(f, "Invalid policy path: {}", err),
×
152
            Self::Signer(err) => write!(f, "Signer error: {}", err),
×
153
            Self::InvalidOutpoint(outpoint) => write!(
×
154
                f,
×
155
                "Requested outpoint doesn't exist in the tx: {}",
×
156
                outpoint
×
157
            ),
×
158
            Self::Descriptor(err) => write!(f, "Descriptor error: {}", err),
×
159
            Self::Miniscript(err) => write!(f, "Miniscript error: {}", err),
×
160
            Self::MiniscriptPsbt(err) => write!(f, "Miniscript PSBT error: {}", err),
×
161
            Self::Bip32(err) => write!(f, "BIP32 error: {}", err),
×
162
            Self::Psbt(err) => write!(f, "PSBT error: {}", err),
×
163
        }
164
    }
×
165
}
166

167
#[cfg(feature = "std")]
168
impl std::error::Error for Error {}
169

170
macro_rules! impl_error {
171
    ( $from:ty, $to:ident ) => {
172
        impl_error!($from, $to, Error);
173
    };
174
    ( $from:ty, $to:ident, $impl_for:ty ) => {
175
        impl core::convert::From<$from> for $impl_for {
176
            fn from(err: $from) -> Self {
34✔
177
                <$impl_for>::$to(err)
34✔
178
            }
34✔
179
        }
180
    };
181
}
182

183
impl_error!(descriptor::error::Error, Descriptor);
184
impl_error!(descriptor::policy::PolicyError, InvalidPolicyPathError);
185
impl_error!(wallet::signer::SignerError, Signer);
186

187
impl From<crate::keys::KeyError> for Error {
188
    fn from(key_error: crate::keys::KeyError) -> Error {
×
189
        match key_error {
×
190
            crate::keys::KeyError::Miniscript(inner) => Error::Miniscript(inner),
×
191
            crate::keys::KeyError::Bip32(inner) => Error::Bip32(inner),
×
192
            crate::keys::KeyError::InvalidChecksum => Error::ChecksumMismatch,
×
193
            e => Error::Key(e),
×
194
        }
195
    }
×
196
}
197

198
impl_error!(miniscript::Error, Miniscript);
199
impl_error!(MiniscriptPsbtError, MiniscriptPsbt);
200
impl_error!(bitcoin::util::bip32::Error, Bip32);
201
impl_error!(bitcoin::util::psbt::Error, Psbt);
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