]> Untitled Git - bdk/commitdiff
Implement conversion for Lightning fee rate
authorVladimir Fomene <vladimirfomene@gmail.com>
Thu, 21 Jul 2022 11:58:30 +0000 (12:58 +0100)
committerVladimir Fomene <vladimirfomene@gmail.com>
Sun, 28 Aug 2022 18:37:07 +0000 (21:37 +0300)
Lightning denotes transaction fee rate
sats / 1000 weight units and sats / 1000 vbytes.
Here we add support for creating BDK fee rate from
lightning fee rate. We also move all FeeRate test to
types.rs and rename as_sat_vb to as_sat_per_vb.

CHANGELOG.md
src/types.rs
src/wallet/coin_selection.rs
src/wallet/mod.rs
src/wallet/utils.rs

index 87b11926839404631d86c8942919bac88b10307f..bfbb180498065caf36c77b6bb3838a61b0ab588c 100644 (file)
@@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
 ## [Unreleased]
+- Add capacity to create FeeRate from sats/kvbytes and sats/kwu.
+- Rename `as_sat_vb` to `as_sat_per_vb`. Move all `FeeRate` test to `types.rs`.
 
 ## [v0.21.0] - [v0.20.0]
 
@@ -19,6 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - New `RpcBlockchain` implementation with various fixes.
 - Return balance in separate categories, namely `confirmed`, `trusted_pending`, `untrusted_pending` & `immature`.
 
+
 ## [v0.20.0] - [v0.19.0]
 
 - New MSRV set to `1.56.1`
index 5e54a3dcdee51c656a678ea951714d5c549e60e3..bae86477f03d038e3eb0a6c8a1d6db226eaf350e 100644 (file)
@@ -63,6 +63,16 @@ impl FeeRate {
         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
@@ -98,7 +108,7 @@ impl FeeRate {
     }
 
     /// Return the value as satoshi/vbyte
-    pub fn as_sat_vb(&self) -> f32 {
+    pub fn as_sat_per_vb(&self) -> f32 {
         self.0
     }
 
@@ -109,7 +119,7 @@ impl FeeRate {
 
     /// Calculate absolute fee in Satoshis using size in virtual bytes.
     pub fn fee_vb(&self, vbytes: usize) -> u64 {
-        (self.as_sat_vb() * vbytes as f32).ceil() as u64
+        (self.as_sat_per_vb() * vbytes as f32).ceil() as u64
     }
 }
 
@@ -358,4 +368,34 @@ mod tests {
     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);
+    }
 }
index 0929bd1dd733a472ef68f3e3bf569b62c070eecc..702ba18558df95e3b778d6d0126d6a80271b5ecf 100644 (file)
@@ -454,7 +454,7 @@ impl<D: Database> CoinSelectionAlgorithm<D> for BranchAndBoundCoinSelection {
             .iter()
             .fold(0, |acc, x| acc + x.effective_value);
 
-        let cost_of_change = self.size_of_change as f32 * fee_rate.as_sat_vb();
+        let cost_of_change = self.size_of_change as f32 * fee_rate.as_sat_per_vb();
 
         // `curr_value` and `curr_available_value` are both the sum of *effective_values* of
         // the UTXOs. For the optional UTXOs (curr_available_value) we filter out UTXOs with
@@ -1360,7 +1360,8 @@ mod test {
         let curr_available_value = utxos.iter().fold(0, |acc, x| acc + x.effective_value);
 
         let size_of_change = 31;
-        let cost_of_change = size_of_change as f32 * fee_rate.as_sat_vb();
+        let cost_of_change = size_of_change as f32 * fee_rate.as_sat_per_vb();
+
         let drain_script = Script::default();
         let target_amount = 20_000 + FEE_AMOUNT;
         BranchAndBoundCoinSelection::new(size_of_change)
@@ -1389,7 +1390,7 @@ mod test {
         let curr_available_value = utxos.iter().fold(0, |acc, x| acc + x.effective_value);
 
         let size_of_change = 31;
-        let cost_of_change = size_of_change as f32 * fee_rate.as_sat_vb();
+        let cost_of_change = size_of_change as f32 * fee_rate.as_sat_per_vb();
         let target_amount = 20_000 + FEE_AMOUNT;
 
         let drain_script = Script::default();
@@ -1413,7 +1414,7 @@ mod test {
     fn test_bnb_function_almost_exact_match_with_fees() {
         let fee_rate = FeeRate::from_sat_per_vb(1.0);
         let size_of_change = 31;
-        let cost_of_change = size_of_change as f32 * fee_rate.as_sat_vb();
+        let cost_of_change = size_of_change as f32 * fee_rate.as_sat_per_vb();
 
         let utxos: Vec<_> = generate_same_value_utxos(50_000, 10)
             .into_iter()
index f7f7dc52699820e6220f33fe2d1e71001043f029..3506b1f5c896725e0336d6e28c5b05b420687731 100644 (file)
@@ -1067,7 +1067,7 @@ where
             utxos: original_utxos,
             bumping_fee: Some(tx_builder::PreviousFee {
                 absolute: details.fee.ok_or(Error::FeeRateUnavailable)?,
-                rate: feerate.as_sat_vb(),
+                rate: feerate.as_sat_per_vb(),
             }),
             ..Default::default()
         };
@@ -2095,7 +2095,7 @@ pub(crate) mod test {
             let fee_rate = $fee_rate;
 
             if !dust_change {
-                assert!(tx_fee_rate >= fee_rate && (tx_fee_rate - fee_rate).as_sat_vb().abs() < 0.5, "Expected fee rate of {:?}, the tx has {:?}", fee_rate, tx_fee_rate);
+                assert!(tx_fee_rate >= fee_rate && (tx_fee_rate - fee_rate).as_sat_per_vb().abs() < 0.5, "Expected fee rate of {:?}, the tx has {:?}", fee_rate, tx_fee_rate);
             } else {
                 assert!(tx_fee_rate >= fee_rate, "Expected fee rate of at least {:?}, the tx has {:?}", fee_rate, tx_fee_rate);
             }
index cee72e40bb32f8351a6657045f0580df07a3ff50..8c072da025ce5cc7228e2310fb75e9d57e80a163 100644 (file)
@@ -144,7 +144,6 @@ mod test {
         SEQUENCE_LOCKTIME_TYPE_FLAG,
     };
     use crate::bitcoin::Address;
-    use crate::types::FeeRate;
     use std::str::FromStr;
 
     #[test]
@@ -164,24 +163,6 @@ mod test {
         assert!(!294.is_dust(&script_p2wpkh));
     }
 
-    #[test]
-    fn test_fee_from_btc_per_kb() {
-        let fee = FeeRate::from_btc_per_kvb(1e-5);
-        assert!((fee.as_sat_vb() - 1.0).abs() < 0.0001);
-    }
-
-    #[test]
-    fn test_fee_from_sats_vbyte() {
-        let fee = FeeRate::from_sat_per_vb(1.0);
-        assert!((fee.as_sat_vb() - 1.0).abs() < 0.0001);
-    }
-
-    #[test]
-    fn test_fee_default_min_relay_fee() {
-        let fee = FeeRate::default_min_relay_fee();
-        assert!((fee.as_sat_vb() - 1.0).abs() < 0.0001);
-    }
-
     #[test]
     fn test_check_nsequence_rbf_msb_set() {
         let result = check_nsequence_rbf(0x80000000, 5000);