[wallet] Add "needed" and "available" metadata to Error::InsufficientFunds
This commit is contained in:
parent
733355a6ae
commit
52b45c5b89
@ -47,7 +47,12 @@ pub enum Error {
|
|||||||
/// Output created is under the dust limit, 546 satoshis
|
/// Output created is under the dust limit, 546 satoshis
|
||||||
OutputBelowDustLimit(usize),
|
OutputBelowDustLimit(usize),
|
||||||
/// Wallet's UTXO set is not enough to cover recipient's requested plus fee
|
/// Wallet's UTXO set is not enough to cover recipient's requested plus fee
|
||||||
InsufficientFunds,
|
InsufficientFunds {
|
||||||
|
/// Sats needed for some transaction
|
||||||
|
needed: u64,
|
||||||
|
/// Sats available for spending
|
||||||
|
available: u64,
|
||||||
|
},
|
||||||
/// Branch and bound coin selection possible attempts with sufficiently big UTXO set could grow
|
/// 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
|
/// exponentially, thus a limit is set, and when hit, this error is thrown
|
||||||
BnBTotalTriesExceeded,
|
BnBTotalTriesExceeded,
|
||||||
|
@ -71,9 +71,9 @@
|
|||||||
//! })
|
//! })
|
||||||
//! .collect::<Vec<_>>();
|
//! .collect::<Vec<_>>();
|
||||||
//! let additional_fees = additional_weight as f32 * fee_rate.as_sat_vb() / 4.0;
|
//! let additional_fees = additional_weight as f32 * fee_rate.as_sat_vb() / 4.0;
|
||||||
//!
|
//! let amount_needed_with_fees = (fee_amount + additional_fees).ceil() as u64 + amount_needed;
|
||||||
//! if (fee_amount + additional_fees).ceil() as u64 + amount_needed > selected_amount {
|
//! if amount_needed_with_fees > selected_amount {
|
||||||
//! return Err(bdk::Error::InsufficientFunds);
|
//! return Err(bdk::Error::InsufficientFunds{ needed: amount_needed_with_fees, available: selected_amount });
|
||||||
//! }
|
//! }
|
||||||
//!
|
//!
|
||||||
//! Ok(CoinSelectionResult {
|
//! Ok(CoinSelectionResult {
|
||||||
@ -221,8 +221,12 @@ impl<D: Database> CoinSelectionAlgorithm<D> for LargestFirstCoinSelection {
|
|||||||
)
|
)
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
if selected_amount < amount_needed + (fee_amount.ceil() as u64) {
|
let amount_needed_with_fees = amount_needed + (fee_amount.ceil() as u64);
|
||||||
return Err(Error::InsufficientFunds);
|
if selected_amount < amount_needed_with_fees {
|
||||||
|
return Err(Error::InsufficientFunds {
|
||||||
|
needed: amount_needed_with_fees,
|
||||||
|
available: selected_amount,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(CoinSelectionResult {
|
Ok(CoinSelectionResult {
|
||||||
@ -321,7 +325,10 @@ impl<D: Database> CoinSelectionAlgorithm<D> for BranchAndBoundCoinSelection {
|
|||||||
let cost_of_change = self.size_of_change as f32 * fee_rate.as_sat_vb();
|
let cost_of_change = self.size_of_change as f32 * fee_rate.as_sat_vb();
|
||||||
|
|
||||||
if curr_available_value + curr_value < actual_target {
|
if curr_available_value + curr_value < actual_target {
|
||||||
return Err(Error::InsufficientFunds);
|
return Err(Error::InsufficientFunds {
|
||||||
|
needed: actual_target,
|
||||||
|
available: curr_available_value + curr_value,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(self
|
Ok(self
|
||||||
|
@ -59,7 +59,10 @@ pub use utils::IsDust;
|
|||||||
use address_validator::AddressValidator;
|
use address_validator::AddressValidator;
|
||||||
use signer::{Signer, SignerId, SignerOrdering, SignersContainer};
|
use signer::{Signer, SignerId, SignerOrdering, SignersContainer};
|
||||||
use tx_builder::{BumpFee, CreateTx, FeePolicy, TxBuilder, TxBuilderContext};
|
use tx_builder::{BumpFee, CreateTx, FeePolicy, TxBuilder, TxBuilderContext};
|
||||||
use utils::{check_nlocktime, check_nsequence_rbf, descriptor_to_pk_ctx, After, Older, SecpCtx};
|
use utils::{
|
||||||
|
check_nlocktime, check_nsequence_rbf, descriptor_to_pk_ctx, After, Older, SecpCtx,
|
||||||
|
DUST_LIMIT_SATOSHI,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::blockchain::{Blockchain, Progress};
|
use crate::blockchain::{Blockchain, Progress};
|
||||||
use crate::database::{BatchDatabase, BatchOperations, DatabaseUtils};
|
use crate::database::{BatchDatabase, BatchOperations, DatabaseUtils};
|
||||||
@ -508,7 +511,11 @@ where
|
|||||||
match change_output {
|
match change_output {
|
||||||
None if change_val.is_dust() => {
|
None if change_val.is_dust() => {
|
||||||
// single recipient, but the only output would be below dust limit
|
// single recipient, but the only output would be below dust limit
|
||||||
return Err(Error::InsufficientFunds); // TODO: or OutputBelowDustLimit?
|
// TODO: or OutputBelowDustLimit?
|
||||||
|
return Err(Error::InsufficientFunds {
|
||||||
|
needed: DUST_LIMIT_SATOSHI,
|
||||||
|
available: change_val,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
Some(_) if change_val.is_dust() => {
|
Some(_) if change_val.is_dust() => {
|
||||||
// skip the change output because it's dust -- just include it in the fee.
|
// skip the change output because it's dust -- just include it in the fee.
|
||||||
@ -786,7 +793,11 @@ where
|
|||||||
}
|
}
|
||||||
Some(_) if change_val_after_add.is_dust() => {
|
Some(_) if change_val_after_add.is_dust() => {
|
||||||
// single_recipient but the only output would be below dust limit
|
// single_recipient but the only output would be below dust limit
|
||||||
return Err(Error::InsufficientFunds); // TODO: or OutputBelowDustLimit?
|
// TODO: or OutputBelowDustLimit?
|
||||||
|
return Err(Error::InsufficientFunds {
|
||||||
|
needed: DUST_LIMIT_SATOSHI,
|
||||||
|
available: change_val_after_add,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
removed_updatable_output.value = change_val_after_add;
|
removed_updatable_output.value = change_val_after_add;
|
||||||
|
@ -29,7 +29,7 @@ use miniscript::descriptor::DescriptorPublicKeyCtx;
|
|||||||
use miniscript::{MiniscriptKey, Satisfier, ToPublicKey};
|
use miniscript::{MiniscriptKey, Satisfier, ToPublicKey};
|
||||||
|
|
||||||
// De-facto standard "dust limit" (even though it should change based on the output type)
|
// De-facto standard "dust limit" (even though it should change based on the output type)
|
||||||
const DUST_LIMIT_SATOSHI: u64 = 546;
|
pub const DUST_LIMIT_SATOSHI: u64 = 546;
|
||||||
|
|
||||||
// MSB of the nSequence. If set there's no consensus-constraint, so it must be disabled when
|
// MSB of the nSequence. If set there's no consensus-constraint, so it must be disabled when
|
||||||
// spending using CSV in order to enforce CSV rules
|
// spending using CSV in order to enforce CSV rules
|
||||||
|
Loading…
x
Reference in New Issue
Block a user