2021-03-03 13:22:05 -08:00
|
|
|
// Bitcoin Dev Kit
|
|
|
|
// Written in 2020 by Alekos Filini <alekos.filini@gmail.com>
|
2020-08-31 11:26:36 +02:00
|
|
|
//
|
2021-03-03 13:22:05 -08:00
|
|
|
// Copyright (c) 2020-2021 Bitcoin Dev Kit Developers
|
2020-08-31 11:26:36 +02:00
|
|
|
//
|
2021-03-03 13:22:05 -08:00
|
|
|
// This file is licensed under the Apache License, Version 2.0 <LICENSE-APACHE
|
|
|
|
// or http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your option.
|
|
|
|
// You may not use this file except in accordance with one or both of these
|
|
|
|
// licenses.
|
2020-08-31 11:26:36 +02:00
|
|
|
|
2020-08-17 10:58:45 +02:00
|
|
|
use std::fmt;
|
|
|
|
|
2020-12-04 14:35:14 +01:00
|
|
|
use crate::{descriptor, wallet, wallet::address_validator};
|
|
|
|
use bitcoin::OutPoint;
|
2020-02-07 23:22:28 +01:00
|
|
|
|
2020-09-04 11:44:49 +02:00
|
|
|
/// Errors that can be thrown by the [`Wallet`](crate::wallet::Wallet)
|
2020-01-27 22:02:55 +01:00
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum Error {
|
2020-12-04 14:35:14 +01:00
|
|
|
/// Wrong number of bytes found when trying to convert to u32
|
2020-02-05 11:59:02 +01:00
|
|
|
InvalidU32Bytes(Vec<u8>),
|
2020-12-04 14:35:14 +01:00
|
|
|
/// Generic error
|
2020-02-05 11:59:02 +01:00
|
|
|
Generic(String),
|
2020-12-04 14:35:14 +01:00
|
|
|
/// This error is thrown when trying to convert Bare and Public key script to address
|
2020-02-07 23:22:28 +01:00
|
|
|
ScriptDoesntHaveAddressForm,
|
2020-12-04 14:35:14 +01:00
|
|
|
/// Found multiple outputs when `single_recipient` option has been specified
|
2020-10-28 10:37:47 +01:00
|
|
|
SingleRecipientMultipleOutputs,
|
2020-12-04 14:35:14 +01:00
|
|
|
/// `single_recipient` option is selected but neither `drain_wallet` nor `manually_selected_only` are
|
2020-10-28 10:37:47 +01:00
|
|
|
SingleRecipientNoInputs,
|
2020-12-04 14:35:14 +01:00
|
|
|
/// Cannot build a tx without recipients
|
2020-10-28 10:37:47 +01:00
|
|
|
NoRecipients,
|
2020-12-04 14:35:14 +01:00
|
|
|
/// `manually_selected_only` option is selected but no utxo has been passed
|
2020-10-28 10:37:47 +01:00
|
|
|
NoUtxosSelected,
|
2020-12-04 14:35:14 +01:00
|
|
|
/// Output created is under the dust limit, 546 satoshis
|
2020-02-07 23:22:28 +01:00
|
|
|
OutputBelowDustLimit(usize),
|
2020-12-04 14:35:14 +01:00
|
|
|
/// Wallet's UTXO set is not enough to cover recipient's requested plus fee
|
2020-11-17 18:05:33 -06:00
|
|
|
InsufficientFunds {
|
|
|
|
/// Sats needed for some transaction
|
|
|
|
needed: u64,
|
|
|
|
/// Sats available for spending
|
|
|
|
available: u64,
|
|
|
|
},
|
2020-12-04 14:35:14 +01:00
|
|
|
/// Branch and bound coin selection possible attempts with sufficiently big UTXO set could grow
|
|
|
|
/// exponentially, thus a limit is set, and when hit, this error is thrown
|
2020-10-31 16:24:59 +01:00
|
|
|
BnBTotalTriesExceeded,
|
2020-12-04 14:35:14 +01:00
|
|
|
/// Branch and bound coin selection tries to avoid needing a change by finding the right inputs for
|
|
|
|
/// the desired outputs plus fee, if there is not such combination this error is thrown
|
2020-10-31 16:24:59 +01:00
|
|
|
BnBNoExactMatch,
|
2020-12-04 14:35:14 +01:00
|
|
|
/// Happens when trying to spend an UTXO that is not in the internal database
|
2020-02-07 23:22:28 +01:00
|
|
|
UnknownUTXO,
|
2020-12-04 14:35:14 +01:00
|
|
|
/// Thrown when a tx is not found in the internal database
|
2020-08-13 16:51:27 +02:00
|
|
|
TransactionNotFound,
|
2020-12-04 14:35:14 +01:00
|
|
|
/// Happens when trying to bump a transaction that is already confirmed
|
2020-08-13 16:51:27 +02:00
|
|
|
TransactionConfirmed,
|
2020-12-07 14:48:17 +01:00
|
|
|
/// Trying to replace a tx that has a sequence >= `0xFFFFFFFE`
|
2020-08-13 16:51:27 +02:00
|
|
|
IrreplaceableTransaction,
|
2020-12-04 14:35:14 +01:00
|
|
|
/// When bumping a tx the fee rate requested is lower than required
|
2020-08-31 10:49:44 +02:00
|
|
|
FeeRateTooLow {
|
2020-12-04 14:35:14 +01:00
|
|
|
/// Required fee rate (satoshi/vbyte)
|
2020-08-31 10:49:44 +02:00
|
|
|
required: crate::types::FeeRate,
|
|
|
|
},
|
2020-12-04 14:35:14 +01:00
|
|
|
/// When bumping a tx the absolute fee requested is lower than replaced tx absolute fee
|
2020-10-22 09:11:58 +02:00
|
|
|
FeeTooLow {
|
2020-12-04 14:35:14 +01:00
|
|
|
/// Required fee absolute value (satoshi)
|
2020-10-22 09:11:58 +02:00
|
|
|
required: u64,
|
|
|
|
},
|
2020-11-30 15:13:33 +01:00
|
|
|
/// In order to use the [`TxBuilder::add_global_xpubs`] option every extended
|
|
|
|
/// key in the descriptor must either be a master key itself (having depth = 0) or have an
|
|
|
|
/// explicit origin provided
|
|
|
|
///
|
|
|
|
/// [`TxBuilder::add_global_xpubs`]: crate::wallet::tx_builder::TxBuilder::add_global_xpubs
|
|
|
|
MissingKeyOrigin(String),
|
2020-12-16 13:57:01 -08:00
|
|
|
/// Error while working with [`keys`](crate::keys)
|
2020-09-21 15:44:07 +02:00
|
|
|
Key(crate::keys::KeyError),
|
2020-12-04 14:35:14 +01:00
|
|
|
/// Descriptor checksum mismatch
|
2020-02-15 21:27:51 +01:00
|
|
|
ChecksumMismatch,
|
2020-12-14 17:14:24 +01:00
|
|
|
/// Spending policy is not compatible with this [`KeychainKind`](crate::types::KeychainKind)
|
|
|
|
SpendingPolicyRequired(crate::types::KeychainKind),
|
2020-12-16 13:57:01 -08:00
|
|
|
/// Error while extracting and manipulating policies
|
2020-02-07 23:22:28 +01:00
|
|
|
InvalidPolicyPathError(crate::descriptor::policy::PolicyError),
|
2020-12-16 13:57:01 -08:00
|
|
|
/// Signing error
|
2020-08-12 12:51:50 +02:00
|
|
|
Signer(crate::wallet::signer::SignerError),
|
2020-02-07 23:22:28 +01:00
|
|
|
|
2020-12-04 14:35:14 +01:00
|
|
|
/// Progress value must be between `0.0` (included) and `100.0` (included)
|
2020-05-03 16:15:11 +02:00
|
|
|
InvalidProgressValue(f32),
|
2020-12-04 14:35:14 +01:00
|
|
|
/// Progress update error (maybe the channel has been closed)
|
2020-05-03 16:15:11 +02:00
|
|
|
ProgressUpdateError,
|
2020-12-04 14:35:14 +01:00
|
|
|
/// Requested outpoint doesn't exist in the tx (vout greater than available outputs)
|
2020-05-03 16:15:11 +02:00
|
|
|
InvalidOutpoint(OutPoint),
|
|
|
|
|
2020-12-16 13:57:01 -08:00
|
|
|
/// Error related to the parsing and usage of descriptors
|
2020-02-07 23:22:28 +01:00
|
|
|
Descriptor(crate::descriptor::error::Error),
|
2020-12-16 13:57:01 -08:00
|
|
|
/// Error that can be returned to fail the validation of an address
|
2020-08-15 23:21:13 +02:00
|
|
|
AddressValidator(crate::wallet::address_validator::AddressValidatorError),
|
2020-12-16 13:57:01 -08:00
|
|
|
/// Encoding error
|
2020-02-05 11:59:02 +01:00
|
|
|
Encode(bitcoin::consensus::encode::Error),
|
2020-12-16 13:57:01 -08:00
|
|
|
/// Miniscript error
|
2020-08-12 12:51:50 +02:00
|
|
|
Miniscript(miniscript::Error),
|
2020-12-16 13:57:01 -08:00
|
|
|
/// BIP32 error
|
2020-01-27 22:02:55 +01:00
|
|
|
BIP32(bitcoin::util::bip32::Error),
|
2020-12-16 13:57:01 -08:00
|
|
|
/// An ECDSA error
|
2020-01-27 22:02:55 +01:00
|
|
|
Secp256k1(bitcoin::secp256k1::Error),
|
2020-12-16 13:57:01 -08:00
|
|
|
/// Error serializing or deserializing JSON data
|
2020-02-05 11:59:02 +01:00
|
|
|
JSON(serde_json::Error),
|
2020-12-16 13:57:01 -08:00
|
|
|
/// Hex decoding error
|
2020-02-07 23:22:28 +01:00
|
|
|
Hex(bitcoin::hashes::hex::Error),
|
2020-12-16 13:57:01 -08:00
|
|
|
/// Partially signed bitcoin transaction error
|
2020-02-07 23:22:28 +01:00
|
|
|
PSBT(bitcoin::util::psbt::Error),
|
2020-02-05 11:59:02 +01:00
|
|
|
|
2020-12-04 14:35:14 +01:00
|
|
|
//KeyMismatch(bitcoin::secp256k1::PublicKey, bitcoin::secp256k1::PublicKey),
|
|
|
|
//MissingInputUTXO(usize),
|
|
|
|
//InvalidAddressNetwork(Address),
|
|
|
|
//DifferentTransactions,
|
|
|
|
//DifferentDescriptorStructure,
|
|
|
|
//Uncapable(crate::blockchain::Capability),
|
|
|
|
//MissingCachedAddresses,
|
2020-05-07 15:14:05 +02:00
|
|
|
#[cfg(feature = "electrum")]
|
2020-12-16 13:57:01 -08:00
|
|
|
/// Electrum client error
|
2020-02-07 23:22:28 +01:00
|
|
|
Electrum(electrum_client::Error),
|
2020-05-07 15:14:05 +02:00
|
|
|
#[cfg(feature = "esplora")]
|
2020-12-16 13:57:01 -08:00
|
|
|
/// Esplora client error
|
2020-05-07 15:14:05 +02:00
|
|
|
Esplora(crate::blockchain::esplora::EsploraError),
|
2020-08-25 16:07:26 +02:00
|
|
|
#[cfg(feature = "compact_filters")]
|
2020-12-16 13:57:01 -08:00
|
|
|
/// Compact filters client error)
|
2020-08-25 16:07:26 +02:00
|
|
|
CompactFilters(crate::blockchain::compact_filters::CompactFiltersError),
|
2020-05-07 15:14:05 +02:00
|
|
|
#[cfg(feature = "key-value-db")]
|
2020-12-16 13:57:01 -08:00
|
|
|
/// Sled database error
|
2020-02-05 11:59:02 +01:00
|
|
|
Sled(sled::Error),
|
2020-01-27 22:02:55 +01:00
|
|
|
}
|
|
|
|
|
2020-08-17 10:58:45 +02:00
|
|
|
impl fmt::Display for Error {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
write!(f, "{:?}", self)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl std::error::Error for Error {}
|
|
|
|
|
2020-01-27 22:02:55 +01:00
|
|
|
macro_rules! impl_error {
|
|
|
|
( $from:ty, $to:ident ) => {
|
2020-12-04 11:23:01 +01:00
|
|
|
impl_error!($from, $to, Error);
|
|
|
|
};
|
|
|
|
( $from:ty, $to:ident, $impl_for:ty ) => {
|
|
|
|
impl std::convert::From<$from> for $impl_for {
|
2020-01-27 22:02:55 +01:00
|
|
|
fn from(err: $from) -> Self {
|
2020-12-04 11:23:01 +01:00
|
|
|
<$impl_for>::$to(err)
|
2020-01-27 22:02:55 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2020-12-04 14:35:14 +01:00
|
|
|
impl_error!(descriptor::error::Error, Descriptor);
|
|
|
|
impl_error!(address_validator::AddressValidatorError, AddressValidator);
|
|
|
|
impl_error!(descriptor::policy::PolicyError, InvalidPolicyPathError);
|
|
|
|
impl_error!(wallet::signer::SignerError, Signer);
|
2020-02-07 23:22:28 +01:00
|
|
|
|
2020-09-21 15:44:07 +02:00
|
|
|
impl From<crate::keys::KeyError> for Error {
|
|
|
|
fn from(key_error: crate::keys::KeyError) -> Error {
|
|
|
|
match key_error {
|
|
|
|
crate::keys::KeyError::Miniscript(inner) => Error::Miniscript(inner),
|
|
|
|
crate::keys::KeyError::BIP32(inner) => Error::BIP32(inner),
|
|
|
|
crate::keys::KeyError::InvalidChecksum => Error::ChecksumMismatch,
|
2020-10-07 14:18:50 -07:00
|
|
|
e => Error::Key(e),
|
2020-09-21 15:44:07 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-05 11:59:02 +01:00
|
|
|
impl_error!(bitcoin::consensus::encode::Error, Encode);
|
2020-08-12 12:51:50 +02:00
|
|
|
impl_error!(miniscript::Error, Miniscript);
|
2020-01-27 22:02:55 +01:00
|
|
|
impl_error!(bitcoin::util::bip32::Error, BIP32);
|
|
|
|
impl_error!(bitcoin::secp256k1::Error, Secp256k1);
|
2020-02-05 11:59:02 +01:00
|
|
|
impl_error!(serde_json::Error, JSON);
|
2020-02-07 23:22:28 +01:00
|
|
|
impl_error!(bitcoin::hashes::hex::Error, Hex);
|
|
|
|
impl_error!(bitcoin::util::psbt::Error, PSBT);
|
2020-02-05 11:59:02 +01:00
|
|
|
|
2020-05-07 15:14:05 +02:00
|
|
|
#[cfg(feature = "electrum")]
|
2020-02-07 23:22:28 +01:00
|
|
|
impl_error!(electrum_client::Error, Electrum);
|
2020-05-07 15:14:05 +02:00
|
|
|
#[cfg(feature = "esplora")]
|
|
|
|
impl_error!(crate::blockchain::esplora::EsploraError, Esplora);
|
|
|
|
#[cfg(feature = "key-value-db")]
|
2020-02-05 11:59:02 +01:00
|
|
|
impl_error!(sled::Error, Sled);
|
2020-08-25 16:07:26 +02:00
|
|
|
|
|
|
|
#[cfg(feature = "compact_filters")]
|
|
|
|
impl From<crate::blockchain::compact_filters::CompactFiltersError> for Error {
|
|
|
|
fn from(other: crate::blockchain::compact_filters::CompactFiltersError) -> Self {
|
|
|
|
match other {
|
|
|
|
crate::blockchain::compact_filters::CompactFiltersError::Global(e) => *e,
|
2020-12-30 19:23:35 -08:00
|
|
|
err => Error::CompactFilters(err),
|
2020-08-25 16:07:26 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|