Skip to content

Commit

Permalink
refactor(bdk)!: drop FeeRate from bdk::types
Browse files Browse the repository at this point in the history
instead adopting `bitcoin::FeeRate` throughout
  • Loading branch information
ValuedMammal committed Nov 14, 2023
1 parent d6a0cf0 commit 429b65c
Show file tree
Hide file tree
Showing 9 changed files with 153 additions and 293 deletions.
8 changes: 4 additions & 4 deletions crates/bdk/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ pub enum Error {
IrreplaceableTransaction,
/// When bumping a tx the fee rate requested is lower than required
FeeRateTooLow {
/// Required fee rate (satoshi/vbyte)
required: crate::types::FeeRate,
/// Required fee rate
required: bitcoin::FeeRate,
},
/// When bumping a tx the absolute fee requested is lower than replaced tx absolute fee
FeeTooLow {
Expand Down Expand Up @@ -137,8 +137,8 @@ impl fmt::Display for Error {
Self::IrreplaceableTransaction => write!(f, "Transaction can't be replaced"),
Self::FeeRateTooLow { required } => write!(
f,
"Fee rate too low: required {} sat/vbyte",
required.as_sat_per_vb()
"Fee rate too low: required {} sat/kwu",
required.to_sat_per_kwu()
),
Self::FeeTooLow { required } => write!(f, "Fee to low: required {} sat", required),
Self::FeeRateUnavailable => write!(f, "Fee rate unavailable"),
Expand Down
5 changes: 3 additions & 2 deletions crates/bdk/src/psbt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@

//! Additional functions on the `rust-bitcoin` `PartiallySignedTransaction` structure.

use crate::FeeRate;
use alloc::vec::Vec;
use bitcoin::psbt::PartiallySignedTransaction as Psbt;
use bitcoin::Amount;
use bitcoin::FeeRate;
use bitcoin::TxOut;

// TODO upstream the functions here to `rust-bitcoin`?
Expand Down Expand Up @@ -73,7 +74,7 @@ impl PsbtUtils for Psbt {
let fee_amount = self.fee_amount();
fee_amount.map(|fee| {
let weight = self.clone().extract_tx().weight();
FeeRate::from_wu(fee, weight)
Amount::from_sat(fee) / weight
})
}
}
167 changes: 3 additions & 164 deletions crates/bdk/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,10 @@

use alloc::boxed::Box;
use core::convert::AsRef;
use core::ops::Sub;

use bdk_chain::ConfirmationTime;
use bitcoin::blockdata::transaction::{OutPoint, TxOut};
use bitcoin::{psbt, Weight};
use bitcoin::psbt;

use serde::{Deserialize, Serialize};

Expand Down Expand Up @@ -47,103 +46,6 @@ impl AsRef<[u8]> for KeychainKind {
}
}

/// Fee rate
#[derive(Debug, Copy, Clone, PartialEq, PartialOrd)]
// Internally stored as satoshi/vbyte
pub struct FeeRate(f32);

impl FeeRate {
/// Create a new instance checking the value provided
///
/// ## Panics
///
/// Panics if the value is not [normal](https://doc.rust-lang.org/std/primitive.f32.html#method.is_normal) (except if it's a positive zero) or negative.
fn new_checked(value: f32) -> Self {
assert!(value.is_normal() || value == 0.0);
assert!(value.is_sign_positive());

FeeRate(value)
}

/// Create a new instance of [`FeeRate`] given a float fee rate in sats/kwu
pub fn from_sat_per_kwu(sat_per_kwu: f32) -> Self {
FeeRate::new_checked(sat_per_kwu / 250.0_f32)
}

/// Create a new instance of [`FeeRate`] given a float fee rate in sats/kvb
pub fn from_sat_per_kvb(sat_per_kvb: f32) -> Self {
FeeRate::new_checked(sat_per_kvb / 1000.0_f32)
}

/// Create a new instance of [`FeeRate`] given a float fee rate in btc/kvbytes
///
/// ## Panics
///
/// Panics if the value is not [normal](https://doc.rust-lang.org/std/primitive.f32.html#method.is_normal) (except if it's a positive zero) or negative.
pub fn from_btc_per_kvb(btc_per_kvb: f32) -> Self {
FeeRate::new_checked(btc_per_kvb * 1e5)
}

/// Create a new instance of [`FeeRate`] given a float fee rate in satoshi/vbyte
///
/// ## Panics
///
/// Panics if the value is not [normal](https://doc.rust-lang.org/std/primitive.f32.html#method.is_normal) (except if it's a positive zero) or negative.
pub fn from_sat_per_vb(sat_per_vb: f32) -> Self {
FeeRate::new_checked(sat_per_vb)
}

/// Create a new [`FeeRate`] with the default min relay fee value
pub const fn default_min_relay_fee() -> Self {
FeeRate(1.0)
}

/// Calculate fee rate from `fee` and weight units (`wu`).
pub fn from_wu(fee: u64, wu: Weight) -> FeeRate {
Self::from_vb(fee, wu.to_vbytes_ceil() as usize)
}

/// Calculate fee rate from `fee` and `vbytes`.
pub fn from_vb(fee: u64, vbytes: usize) -> FeeRate {
let rate = fee as f32 / vbytes as f32;
Self::from_sat_per_vb(rate)
}

/// Return the value as satoshi/vbyte
pub fn as_sat_per_vb(&self) -> f32 {
self.0
}

/// Return the value as satoshi/kwu
pub fn sat_per_kwu(&self) -> f32 {
self.0 * 250.0_f32
}

/// Calculate absolute fee in Satoshis using size in weight units.
pub fn fee_wu(&self, wu: Weight) -> u64 {
self.fee_vb(wu.to_vbytes_ceil() as usize)
}

/// Calculate absolute fee in Satoshis using size in virtual bytes.
pub fn fee_vb(&self, vbytes: usize) -> u64 {
(self.as_sat_per_vb() * vbytes as f32).ceil() as u64
}
}

impl Default for FeeRate {
fn default() -> Self {
FeeRate::default_min_relay_fee()
}
}

impl Sub for FeeRate {
type Output = Self;

fn sub(self, other: FeeRate) -> Self::Output {
FeeRate(self.0 - other.0)
}
}

/// Trait implemented by types that can be used to measure weight units.
pub trait Vbytes {
/// Convert weight units to virtual bytes.
Expand Down Expand Up @@ -236,70 +138,7 @@ impl Utxo {

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn can_store_feerate_in_const() {
const _MIN_RELAY: FeeRate = FeeRate::default_min_relay_fee();
}

#[test]
#[should_panic]
fn test_invalid_feerate_neg_zero() {
let _ = FeeRate::from_sat_per_vb(-0.0);
}

#[test]
#[should_panic]
fn test_invalid_feerate_neg_value() {
let _ = FeeRate::from_sat_per_vb(-5.0);
}
//use super::*;

#[test]
#[should_panic]
fn test_invalid_feerate_nan() {
let _ = FeeRate::from_sat_per_vb(f32::NAN);
}

#[test]
#[should_panic]
fn test_invalid_feerate_inf() {
let _ = FeeRate::from_sat_per_vb(f32::INFINITY);
}

#[test]
fn test_valid_feerate_pos_zero() {
let _ = FeeRate::from_sat_per_vb(0.0);
}

#[test]
fn test_fee_from_btc_per_kvb() {
let fee = FeeRate::from_btc_per_kvb(1e-5);
assert!((fee.as_sat_per_vb() - 1.0).abs() < f32::EPSILON);
}

#[test]
fn test_fee_from_sat_per_vbyte() {
let fee = FeeRate::from_sat_per_vb(1.0);
assert!((fee.as_sat_per_vb() - 1.0).abs() < f32::EPSILON);
}

#[test]
fn test_fee_default_min_relay_fee() {
let fee = FeeRate::default_min_relay_fee();
assert!((fee.as_sat_per_vb() - 1.0).abs() < f32::EPSILON);
}

#[test]
fn test_fee_from_sat_per_kvb() {
let fee = FeeRate::from_sat_per_kvb(1000.0);
assert!((fee.as_sat_per_vb() - 1.0).abs() < f32::EPSILON);
}

#[test]
fn test_fee_from_sat_per_kwu() {
let fee = FeeRate::from_sat_per_kwu(250.0);
assert!((fee.as_sat_per_vb() - 1.0).abs() < f32::EPSILON);
assert_eq!(fee.sat_per_kwu(), 250.0);
}
// TODO: decide what goes here
}
Loading

0 comments on commit 429b65c

Please sign in to comment.