diff --git a/src/wallet/coin_selection.rs b/src/wallet/coin_selection.rs index e3729bbc..978f3d16 100644 --- a/src/wallet/coin_selection.rs +++ b/src/wallet/coin_selection.rs @@ -90,6 +90,7 @@ //! ``` use crate::types::FeeRate; +use crate::wallet::Vbytes; use crate::{database::Database, WeightedUtxo}; use crate::{error::Error, Utxo}; @@ -257,8 +258,8 @@ struct OutputGroup { impl OutputGroup { fn new(weighted_utxo: WeightedUtxo, fee_rate: FeeRate) -> Self { - let fee = (TXIN_BASE_WEIGHT + weighted_utxo.satisfaction_weight) as f32 / 4.0 - * fee_rate.as_sat_vb(); + let fee = + (TXIN_BASE_WEIGHT + weighted_utxo.satisfaction_weight).vbytes() * fee_rate.as_sat_vb(); let effective_value = weighted_utxo.utxo.txout().value as i64 - fee.ceil() as i64; OutputGroup { weighted_utxo, @@ -862,7 +863,7 @@ mod test { assert_eq!(result.selected.len(), 1); assert_eq!(result.selected_amount(), 100_000); - let input_size = (TXIN_BASE_WEIGHT as f32) / 4.0 + P2WPKH_WITNESS_SIZE as f32 / 4.0; + let input_size = (TXIN_BASE_WEIGHT + P2WPKH_WITNESS_SIZE).vbytes(); let epsilon = 0.5; assert!((1.0 - (result.fee_amount / input_size)).abs() < epsilon); } diff --git a/src/wallet/mod.rs b/src/wallet/mod.rs index e29b8a62..55dd7110 100644 --- a/src/wallet/mod.rs +++ b/src/wallet/mod.rs @@ -780,7 +780,7 @@ where return Err(Error::IrreplaceableTransaction); } - let vbytes = tx.get_weight() as f32 / 4.0; + let vbytes = tx.get_weight().vbytes(); let feerate = details.fee.ok_or(Error::FeeRateUnavailable)? as f32 / vbytes; // remove the inputs from the tx and process them @@ -1578,6 +1578,18 @@ where } } +/// Trait implemented by types that can be used to measure weight units. +pub trait Vbytes { + /// Convert weight units to virtual bytes. + fn vbytes(self) -> f32; +} + +impl Vbytes for usize { + fn vbytes(self) -> f32 { + self as f32 / 4.0 + } +} + #[cfg(test)] pub(crate) mod test { use std::str::FromStr; @@ -1764,7 +1776,7 @@ pub(crate) mod test { dust_change = true; )* - let tx_fee_rate = $fees as f32 / (tx.get_weight() as f32 / 4.0); + let tx_fee_rate = $fees as f32 / (tx.get_weight().vbytes()); let fee_rate = $fee_rate.as_sat_vb(); if !dust_change {