diff --git a/dash/src/blockdata/fee_rate.rs b/dash/src/blockdata/fee_rate.rs deleted file mode 100644 index 5514095e9..000000000 --- a/dash/src/blockdata/fee_rate.rs +++ /dev/null @@ -1,202 +0,0 @@ -//! Implements `FeeRate` and assoctiated features. - -use core::fmt; -use core::ops::{Div, Mul}; - -use super::Weight; -use crate::Amount; -use crate::prelude::*; - -/// Represents fee rate. -/// -/// This is an integer newtype representing fee rate in `sat/kwu`. It provides protection against mixing -/// up the types as well as basic formatting features. -#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] -#[cfg_attr(feature = "serde", serde(transparent))] -pub struct FeeRate(u64); - -impl FeeRate { - /// 0 sat/kwu. - /// - /// Equivalent to [`MIN`](Self::MIN), may better express intent in some contexts. - pub const ZERO: FeeRate = FeeRate(0); - - /// Minimum possible value (0 sat/kwu). - /// - /// Equivalent to [`ZERO`](Self::ZERO), may better express intent in some contexts. - pub const MIN: FeeRate = FeeRate(u64::MIN); - - /// Maximum possible value. - pub const MAX: FeeRate = FeeRate(u64::MAX); - - /// Minimum fee rate required to broadcast a transaction. - /// - /// The value matches the default Bitcoin Core policy at the time of library release. - pub const BROADCAST_MIN: FeeRate = FeeRate::from_sat_per_vb_unchecked(1); - - /// Fee rate used to compute dust amount. - pub const DUST: FeeRate = FeeRate::from_sat_per_vb_unchecked(3); - - /// Constructs `FeeRate` from satoshis per 1000 weight units. - pub const fn from_sat_per_kwu(sat_kwu: u64) -> Self { - FeeRate(sat_kwu) - } - - /// Constructs `FeeRate` from satoshis per virtual bytes. - /// - /// # Errors - /// - /// Returns `None` on arithmetic overflow. - pub fn from_sat_per_vb(sat_vb: u64) -> Option { - // 1 vb == 4 wu - // 1 sat/vb == 1/4 sat/wu - // sat_vb sat/vb * 1000 / 4 == sat/kwu - Some(FeeRate(sat_vb.checked_mul(1000 / 4)?)) - } - - /// Constructs `FeeRate` from satoshis per virtual bytes without overflow check. - pub const fn from_sat_per_vb_unchecked(sat_vb: u64) -> Self { - FeeRate(sat_vb * (1000 / 4)) - } - - /// Returns raw fee rate. - /// - /// Can be used instead of `into()` to avoid inference issues. - pub const fn to_sat_per_kwu(self) -> u64 { - self.0 - } - - /// Converts to sat/vB rounding down. - pub const fn to_sat_per_vb_floor(self) -> u64 { - self.0 / (1000 / 4) - } - - /// Converts to sat/vB rounding up. - pub const fn to_sat_per_vb_ceil(self) -> u64 { - self.0.div_ceil(1000 / 4) - } - - /// Checked multiplication. - /// - /// Computes `self * rhs` returning `None` if overflow occurred. - pub fn checked_mul(self, rhs: u64) -> Option { - self.0.checked_mul(rhs).map(Self) - } - - /// Checked division. - /// - /// Computes `self / rhs` returning `None` if `rhs == 0`. - pub fn checked_div(self, rhs: u64) -> Option { - self.0.checked_div(rhs).map(Self) - } -} - -/// Alternative will display the unit. -impl fmt::Display for FeeRate { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - if f.alternate() { - write!(f, "{} sat/kwu", self.0) - } else { - fmt::Display::fmt(&self.0, f) - } - } -} - -impl From for u64 { - fn from(value: FeeRate) -> Self { - value.to_sat_per_kwu() - } -} - -/// Computes ceiling so that fee computation is conservative. -impl Mul for Weight { - type Output = Amount; - - fn mul(self, rhs: FeeRate) -> Self::Output { - Amount::from_sat((rhs.to_sat_per_kwu() * self.to_wu()).div_ceil(1000)) - } -} - -impl Mul for FeeRate { - type Output = Amount; - - fn mul(self, rhs: Weight) -> Self::Output { - rhs * self - } -} - -impl Div for Amount { - type Output = FeeRate; - - fn div(self, rhs: Weight) -> Self::Output { - FeeRate(self.to_sat() * 1000 / rhs.to_wu()) - } -} - -crate::parse::impl_parse_str_from_int_infallible!(FeeRate, u64, from_sat_per_kwu); - -#[cfg(test)] -mod tests { - - use super::*; - - #[test] - fn fee_rate_const_test() { - assert_eq!(0, FeeRate::ZERO.to_sat_per_kwu()); - assert_eq!(u64::MIN, FeeRate::MIN.to_sat_per_kwu()); - assert_eq!(u64::MAX, FeeRate::MAX.to_sat_per_kwu()); - assert_eq!(250, FeeRate::BROADCAST_MIN.to_sat_per_kwu()); - assert_eq!(750, FeeRate::DUST.to_sat_per_kwu()); - } - - #[test] - fn fee_rate_from_sat_per_vb_test() { - let fee_rate = FeeRate::from_sat_per_vb(10).expect("expected feerate in sat/kwu"); - assert_eq!(FeeRate(2500), fee_rate); - } - - #[test] - fn fee_rate_from_sat_per_vb_overflow_test() { - let fee_rate = FeeRate::from_sat_per_vb(u64::MAX); - assert!(fee_rate.is_none()); - } - - #[test] - fn from_sat_per_vb_unchecked_test() { - let fee_rate = FeeRate::from_sat_per_vb_unchecked(10); - assert_eq!(FeeRate(2500), fee_rate); - } - - #[test] - #[should_panic] - fn from_sat_per_vb_unchecked_panic_test() { - FeeRate::from_sat_per_vb_unchecked(u64::MAX); - } - - #[test] - fn raw_feerate_test() { - let fee_rate = FeeRate(333); - assert_eq!(333, fee_rate.to_sat_per_kwu()); - assert_eq!(1, fee_rate.to_sat_per_vb_floor()); - assert_eq!(2, fee_rate.to_sat_per_vb_ceil()); - } - - #[test] - fn checked_mul_test() { - let fee_rate = FeeRate(10).checked_mul(10).expect("expected feerate in sat/kwu"); - assert_eq!(FeeRate(100), fee_rate); - - let fee_rate = FeeRate(10).checked_mul(u64::MAX); - assert!(fee_rate.is_none()); - } - - #[test] - fn checked_div_test() { - let fee_rate = FeeRate(10).checked_div(10).expect("expected feerate in sat/kwu"); - assert_eq!(FeeRate(1), fee_rate); - - let fee_rate = FeeRate(10).checked_div(0); - assert!(fee_rate.is_none()); - } -} diff --git a/dash/src/blockdata/mod.rs b/dash/src/blockdata/mod.rs index 12cc342a7..d6b117ff3 100644 --- a/dash/src/blockdata/mod.rs +++ b/dash/src/blockdata/mod.rs @@ -9,7 +9,6 @@ pub mod block; pub mod constants; -pub mod fee_rate; pub mod locktime; pub mod opcodes; pub mod script; @@ -17,5 +16,4 @@ pub mod transaction; pub mod weight; pub mod witness; -pub use fee_rate::FeeRate; pub use weight::Weight; diff --git a/dash/src/lib.rs b/dash/src/lib.rs index d47da3d24..608b41c79 100644 --- a/dash/src/lib.rs +++ b/dash/src/lib.rs @@ -140,7 +140,6 @@ use core2::io; pub use crate::address::{Address, AddressType}; pub use crate::amount::{Amount, Denomination, SignedAmount}; pub use crate::blockdata::block::{self, Block, Header}; -pub use crate::blockdata::fee_rate::FeeRate; pub use crate::blockdata::locktime::{self, absolute, relative}; pub use crate::blockdata::script::{self, Script, ScriptBuf}; pub use crate::blockdata::transaction::{self, Transaction};