Add Vbytes trait

We convert weight units into vbytes in various places. Lets add a trait
to do it, this makes the code slightly cleaner.
This commit is contained in:
Tobin Harding 2021-07-08 11:33:39 +10:00
parent e5d4994329
commit c1077b95cf
No known key found for this signature in database
GPG Key ID: 40BF9E4C269D6607
2 changed files with 18 additions and 5 deletions

View File

@ -90,6 +90,7 @@
//! ``` //! ```
use crate::types::FeeRate; use crate::types::FeeRate;
use crate::wallet::Vbytes;
use crate::{database::Database, WeightedUtxo}; use crate::{database::Database, WeightedUtxo};
use crate::{error::Error, Utxo}; use crate::{error::Error, Utxo};
@ -257,8 +258,8 @@ struct OutputGroup {
impl OutputGroup { impl OutputGroup {
fn new(weighted_utxo: WeightedUtxo, fee_rate: FeeRate) -> Self { fn new(weighted_utxo: WeightedUtxo, fee_rate: FeeRate) -> Self {
let fee = (TXIN_BASE_WEIGHT + weighted_utxo.satisfaction_weight) as f32 / 4.0 let fee =
* fee_rate.as_sat_vb(); (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; let effective_value = weighted_utxo.utxo.txout().value as i64 - fee.ceil() as i64;
OutputGroup { OutputGroup {
weighted_utxo, weighted_utxo,
@ -862,7 +863,7 @@ mod test {
assert_eq!(result.selected.len(), 1); assert_eq!(result.selected.len(), 1);
assert_eq!(result.selected_amount(), 100_000); 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; let epsilon = 0.5;
assert!((1.0 - (result.fee_amount / input_size)).abs() < epsilon); assert!((1.0 - (result.fee_amount / input_size)).abs() < epsilon);
} }

View File

@ -780,7 +780,7 @@ where
return Err(Error::IrreplaceableTransaction); 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; let feerate = details.fee.ok_or(Error::FeeRateUnavailable)? as f32 / vbytes;
// remove the inputs from the tx and process them // 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)] #[cfg(test)]
pub(crate) mod test { pub(crate) mod test {
use std::str::FromStr; use std::str::FromStr;
@ -1764,7 +1776,7 @@ pub(crate) mod test {
dust_change = true; 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(); let fee_rate = $fee_rate.as_sat_vb();
if !dust_change { if !dust_change {