2020-08-31 11:26:36 +02:00
// Magical Bitcoin Library
// Written in 2020 by
// Alekos Filini <alekos.filini@gmail.com>
//
// Copyright (c) 2020 Magical Bitcoin
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
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-02-07 23:22:28 +01:00
InsufficientFunds ,
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-04 14:35:14 +01:00
/// Trying to replace a tx that has a sequence = `0xFFFFFFFF`
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-04 14:35:14 +01:00
#[ allow(missing_docs) ]
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-07 10:56:01 -08:00
/// Spending policy is not compatible with this [`ScriptType`](crate::types::ScriptType)
2020-11-10 15:06:14 +01:00
SpendingPolicyRequired ( crate ::types ::ScriptType ) ,
2020-12-04 14:35:14 +01:00
#[ allow(missing_docs) ]
2020-02-07 23:22:28 +01:00
InvalidPolicyPathError ( crate ::descriptor ::policy ::PolicyError ) ,
2020-12-04 14:35:14 +01:00
#[ allow(missing_docs) ]
2020-08-12 12:51:50 +02:00
Signer ( crate ::wallet ::signer ::SignerError ) ,
2020-02-07 23:22:28 +01:00
2020-05-03 16:15:11 +02:00
// Blockchain interface errors
2020-12-07 10:56:01 -08:00
/// Thrown when trying to call a method that requires a network connection, [`Wallet::sync`](crate::Wallet::sync) and [`Wallet::broadcast`](crate::Wallet::broadcast)
2020-12-04 14:35:14 +01:00
/// This error is thrown when creating the Client for the first time, while recovery attempts are tried
/// during the sync
2020-05-06 16:50:03 +02:00
OfflineClient ,
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-04 14:35:14 +01:00
#[ allow(missing_docs) ]
2020-02-07 23:22:28 +01:00
Descriptor ( crate ::descriptor ::error ::Error ) ,
2020-12-04 14:35:14 +01:00
#[ allow(missing_docs) ]
2020-08-15 23:21:13 +02:00
AddressValidator ( crate ::wallet ::address_validator ::AddressValidatorError ) ,
2020-12-04 14:35:14 +01:00
#[ allow(missing_docs) ]
2020-02-05 11:59:02 +01:00
Encode ( bitcoin ::consensus ::encode ::Error ) ,
2020-12-04 14:35:14 +01:00
#[ allow(missing_docs) ]
2020-08-12 12:51:50 +02:00
Miniscript ( miniscript ::Error ) ,
2020-12-04 14:35:14 +01:00
#[ allow(missing_docs) ]
2020-01-27 22:02:55 +01:00
BIP32 ( bitcoin ::util ::bip32 ::Error ) ,
2020-12-04 14:35:14 +01:00
#[ allow(missing_docs) ]
2020-01-27 22:02:55 +01:00
Secp256k1 ( bitcoin ::secp256k1 ::Error ) ,
2020-12-04 14:35:14 +01:00
#[ allow(missing_docs) ]
2020-02-05 11:59:02 +01:00
JSON ( serde_json ::Error ) ,
2020-12-04 14:35:14 +01:00
#[ allow(missing_docs) ]
2020-02-07 23:22:28 +01:00
Hex ( bitcoin ::hashes ::hex ::Error ) ,
2020-12-04 14:35:14 +01:00
#[ allow(missing_docs) ]
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-04 14:35:14 +01:00
#[ allow(missing_docs) ]
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-04 14:35:14 +01:00
#[ allow(missing_docs) ]
2020-05-07 15:14:05 +02:00
Esplora ( crate ::blockchain ::esplora ::EsploraError ) ,
2020-12-04 14:35:14 +01:00
#[ allow(missing_docs) ]
2020-08-25 16:07:26 +02:00
#[ cfg(feature = " compact_filters " ) ]
CompactFilters ( crate ::blockchain ::compact_filters ::CompactFiltersError ) ,
2020-05-07 15:14:05 +02:00
#[ cfg(feature = " key-value-db " ) ]
2020-12-04 14:35:14 +01:00
#[ allow(missing_docs) ]
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 ,
err @ _ = > Error ::CompactFilters ( err ) ,
}
}
}