feat: use Amount on calculate_fee, fee_absolute, fee_amount and others
- update to use `bitcoin::Amount` on `CreateTxError::FeeTooLow` variant. - update to use `bitcoin::Amount` on `Wallet::calculate_fee()`. - update to use `bitcoin::Amount` on `FeePolicy::fee_absolute()`. - update to use `bitcoin::SignedAmount` on `CalculateFeeError::NegativeFee` variant. - update to use `bitcoin::Amount` on `TxGraph::calculate_fee()`. - update to use `bitcoin::Amount` on `PsbUtils::fee_amount()`
This commit is contained in:
@@ -26,7 +26,7 @@ pub trait PsbtUtils {
|
||||
|
||||
/// The total transaction fee amount, sum of input amounts minus sum of output amounts, in sats.
|
||||
/// If the PSBT is missing a TxOut for an input returns None.
|
||||
fn fee_amount(&self) -> Option<u64>;
|
||||
fn fee_amount(&self) -> Option<Amount>;
|
||||
|
||||
/// The transaction's fee rate. This value will only be accurate if calculated AFTER the
|
||||
/// `Psbt` is finalized and all witness/signature data is added to the
|
||||
@@ -49,18 +49,13 @@ impl PsbtUtils for Psbt {
|
||||
}
|
||||
}
|
||||
|
||||
fn fee_amount(&self) -> Option<u64> {
|
||||
fn fee_amount(&self) -> Option<Amount> {
|
||||
let tx = &self.unsigned_tx;
|
||||
let utxos: Option<Vec<TxOut>> = (0..tx.input.len()).map(|i| self.get_utxo_for(i)).collect();
|
||||
|
||||
utxos.map(|inputs| {
|
||||
let input_amount: u64 = inputs.iter().map(|i| i.value.to_sat()).sum();
|
||||
let output_amount: u64 = self
|
||||
.unsigned_tx
|
||||
.output
|
||||
.iter()
|
||||
.map(|o| o.value.to_sat())
|
||||
.sum();
|
||||
let input_amount: Amount = inputs.iter().map(|i| i.value).sum();
|
||||
let output_amount: Amount = self.unsigned_tx.output.iter().map(|o| o.value).sum();
|
||||
input_amount
|
||||
.checked_sub(output_amount)
|
||||
.expect("input amount must be greater than output amount")
|
||||
@@ -70,6 +65,6 @@ impl PsbtUtils for Psbt {
|
||||
fn fee_rate(&self) -> Option<FeeRate> {
|
||||
let fee_amount = self.fee_amount();
|
||||
let weight = self.clone().extract_tx().ok()?.weight();
|
||||
fee_amount.map(|fee| Amount::from_sat(fee) / weight)
|
||||
fee_amount.map(|fee| fee / weight)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ use crate::descriptor::DescriptorError;
|
||||
use crate::wallet::coin_selection;
|
||||
use crate::{descriptor, KeychainKind};
|
||||
use alloc::string::String;
|
||||
use bitcoin::{absolute, psbt, OutPoint, Sequence, Txid};
|
||||
use bitcoin::{absolute, psbt, Amount, OutPoint, Sequence, Txid};
|
||||
use core::fmt;
|
||||
|
||||
/// Errors returned by miniscript when updating inconsistent PSBTs
|
||||
@@ -78,8 +78,8 @@ pub enum CreateTxError {
|
||||
},
|
||||
/// When bumping a tx the absolute fee requested is lower than replaced tx absolute fee
|
||||
FeeTooLow {
|
||||
/// Required fee absolute value (satoshi)
|
||||
required: u64,
|
||||
/// Required fee absolute value [`Amount`]
|
||||
required: Amount,
|
||||
},
|
||||
/// When bumping a tx the fee rate requested is lower than required
|
||||
FeeRateTooLow {
|
||||
@@ -160,7 +160,7 @@ impl fmt::Display for CreateTxError {
|
||||
)
|
||||
}
|
||||
CreateTxError::FeeTooLow { required } => {
|
||||
write!(f, "Fee to low: required {} sat", required)
|
||||
write!(f, "Fee to low: required {}", required.display_dynamic())
|
||||
}
|
||||
CreateTxError::FeeRateTooLow { required } => {
|
||||
write!(
|
||||
|
||||
@@ -977,7 +977,7 @@ impl Wallet {
|
||||
self.persist.stage(ChangeSet::from(additions));
|
||||
}
|
||||
|
||||
/// Calculates the fee of a given transaction. Returns 0 if `tx` is a coinbase transaction.
|
||||
/// Calculates the fee of a given transaction. Returns [`Amount::ZERO`] if `tx` is a coinbase transaction.
|
||||
///
|
||||
/// To calculate the fee for a [`Transaction`] with inputs not owned by this wallet you must
|
||||
/// manually insert the TxOut(s) into the tx graph using the [`insert_txout`] function.
|
||||
@@ -1004,7 +1004,7 @@ impl Wallet {
|
||||
/// let fee = wallet.calculate_fee(tx).expect("fee");
|
||||
/// ```
|
||||
/// [`insert_txout`]: Self::insert_txout
|
||||
pub fn calculate_fee(&self, tx: &Transaction) -> Result<u64, CalculateFeeError> {
|
||||
pub fn calculate_fee(&self, tx: &Transaction) -> Result<Amount, CalculateFeeError> {
|
||||
self.indexed_graph.graph().calculate_fee(tx)
|
||||
}
|
||||
|
||||
@@ -1036,8 +1036,7 @@ impl Wallet {
|
||||
/// ```
|
||||
/// [`insert_txout`]: Self::insert_txout
|
||||
pub fn calculate_fee_rate(&self, tx: &Transaction) -> Result<FeeRate, CalculateFeeError> {
|
||||
self.calculate_fee(tx)
|
||||
.map(|fee| Amount::from_sat(fee) / tx.weight())
|
||||
self.calculate_fee(tx).map(|fee| fee / tx.weight())
|
||||
}
|
||||
|
||||
/// Compute the `tx`'s sent and received [`Amount`]s.
|
||||
@@ -1465,7 +1464,7 @@ impl Wallet {
|
||||
if let Some(previous_fee) = params.bumping_fee {
|
||||
if fee < previous_fee.absolute {
|
||||
return Err(CreateTxError::FeeTooLow {
|
||||
required: previous_fee.absolute,
|
||||
required: Amount::from_sat(previous_fee.absolute),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1498,9 +1497,8 @@ impl Wallet {
|
||||
return Err(CreateTxError::NoUtxosSelected);
|
||||
}
|
||||
|
||||
// we keep it as a float while we accumulate it, and only round it at the end
|
||||
let mut outgoing: u64 = 0;
|
||||
let mut received: u64 = 0;
|
||||
let mut outgoing = Amount::ZERO;
|
||||
let mut received = Amount::ZERO;
|
||||
|
||||
let recipients = params.recipients.iter().map(|(r, v)| (r, *v));
|
||||
|
||||
@@ -1513,7 +1511,7 @@ impl Wallet {
|
||||
}
|
||||
|
||||
if self.is_mine(script_pubkey) {
|
||||
received += value;
|
||||
received += Amount::from_sat(value);
|
||||
}
|
||||
|
||||
let new_out = TxOut {
|
||||
@@ -1523,7 +1521,7 @@ impl Wallet {
|
||||
|
||||
tx.output.push(new_out);
|
||||
|
||||
outgoing += value;
|
||||
outgoing += Amount::from_sat(value);
|
||||
}
|
||||
|
||||
fee_amount += (fee_rate * tx.weight()).to_sat();
|
||||
@@ -1565,7 +1563,7 @@ impl Wallet {
|
||||
required_utxos,
|
||||
optional_utxos,
|
||||
fee_rate,
|
||||
outgoing + fee_amount,
|
||||
outgoing.to_sat() + fee_amount,
|
||||
&drain_script,
|
||||
)?;
|
||||
fee_amount += coin_selection.fee_amount;
|
||||
@@ -1613,7 +1611,7 @@ impl Wallet {
|
||||
} => fee_amount += remaining_amount,
|
||||
Change { amount, fee } => {
|
||||
if self.is_mine(&drain_script) {
|
||||
received += amount;
|
||||
received += Amount::from_sat(*amount);
|
||||
}
|
||||
fee_amount += fee;
|
||||
|
||||
@@ -1797,7 +1795,7 @@ impl Wallet {
|
||||
.collect(),
|
||||
utxos: original_utxos,
|
||||
bumping_fee: Some(tx_builder::PreviousFee {
|
||||
absolute: fee,
|
||||
absolute: fee.to_sat(),
|
||||
rate: fee_rate,
|
||||
}),
|
||||
..Default::default()
|
||||
|
||||
@@ -186,10 +186,10 @@ impl<'a, Cs> TxBuilder<'a, Cs> {
|
||||
}
|
||||
|
||||
/// Set an absolute fee
|
||||
/// The fee_absolute method refers to the absolute transaction fee in satoshis (sats).
|
||||
/// If anyone sets both the fee_absolute method and the fee_rate method,
|
||||
/// the FeePolicy enum will be set by whichever method was called last,
|
||||
/// as the FeeRate and FeeAmount are mutually exclusive.
|
||||
/// The fee_absolute method refers to the absolute transaction fee in [`Amount`].
|
||||
/// If anyone sets both the `fee_absolute` method and the `fee_rate` method,
|
||||
/// the `FeePolicy` enum will be set by whichever method was called last,
|
||||
/// as the [`FeeRate`] and `FeeAmount` are mutually exclusive.
|
||||
///
|
||||
/// Note that this is really a minimum absolute fee -- it's possible to
|
||||
/// overshoot it slightly since adding a change output to drain the remaining
|
||||
|
||||
Reference in New Issue
Block a user