Skip to content

Commit

Permalink
move, document and test the FeeRate struct
Browse files Browse the repository at this point in the history
  • Loading branch information
sander2 committed Aug 19, 2022
1 parent e4a5f71 commit ad5535d
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 20 deletions.
2 changes: 1 addition & 1 deletion integration_test/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,7 @@ fn test_bump_fee(cl: &Client) {

// bump with explicit fee rate
let amount_per_vbyte = Amount::from_sat(500);
let new_fee_rate = json::FeeRate::new(amount_per_vbyte);
let new_fee_rate = json::FeeRate::per_vbyte(amount_per_vbyte);
let options = json::BumpFeeOptions {
fee_rate: Some(new_fee_rate),
replaceable: Some(true),
Expand Down
67 changes: 48 additions & 19 deletions json/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,37 @@ use std::fmt;

//TODO(stevenroose) consider using a Time type

/// A representation of a fee rate. Bitcoin Core uses different units in different
/// versions. To avoid burdening the user with using the correct unit, this struct
/// provides an umambiguous way to represent the fee rate, and the lib will perform
/// the necessary conversions.
#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
pub struct FeeRate(Amount);

impl FeeRate {
/// Construct FeeRate from the amount per vbyte
pub fn per_vbyte(amount_per_vbyte: Amount) -> Self {
// internal representation is amount per vbyte
Self(amount_per_vbyte)
}

/// Construct FeeRate from the amount per kilo-vbyte
pub fn per_kvbyte(amount_per_kvbyte: Amount) -> Self {
// internal representation is amount per vbyte, so divide by 1000
Self::per_vbyte(amount_per_kvbyte / 1000)
}

pub fn as_sat_per_vbyte(&self) -> f64 {
// multiply by the number of decimals to get sat
self.0.as_sat() as f64
}

pub fn as_btc_per_kvbyte(&self) -> f64 {
// divide by 10^8 to get btc/vbyte, then multiply by 10^3 to get btc/kbyte
self.0.as_sat() as f64 / 100_000.0
}
}

/// A module used for serde serialization of bytes in hexadecimal format.
///
/// The module is compatible with the serde attribute.
Expand Down Expand Up @@ -1827,9 +1858,9 @@ impl BumpFeeOptions {
pub fn to_serializable(&self, version: usize) -> SerializableBumpFeeOptions {
let fee_rate = self.fee_rate.map(|x| {
if version < 210000 {
x.btc_per_kvbyte()
x.as_btc_per_kvbyte()
} else {
x.sat_per_vbyte()
x.as_sat_per_vbyte()
}
});

Expand All @@ -1842,23 +1873,6 @@ impl BumpFeeOptions {
}
}

#[derive(Copy, Clone, PartialEq, Eq, Debug, Default)]
pub struct FeeRate(Amount);

impl FeeRate {
pub fn new(amount_per_vbyte: Amount) -> Self {
Self(amount_per_vbyte)
}
pub fn sat_per_vbyte(&self) -> f64 {
// multiply by the number of decimals to get sat
self.0.as_sat() as f64
}
pub fn btc_per_kvbyte(&self) -> f64 {
// divide by 10^8 to get btc/vbyte, then multiply by 10^3 to get btc/kbyte
self.0.as_sat() as f64 / 100_000.0
}
}

#[derive(Serialize, Clone, PartialEq, Debug, Default)]
#[serde(rename_all = "camelCase")]
pub struct SerializableBumpFeeOptions {
Expand Down Expand Up @@ -2072,3 +2086,18 @@ where
}
Ok(Some(res))
}

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

#[test]
fn test_fee_rate_conversion() {
let rate_1 = FeeRate::per_kvbyte(Amount::from_sat(10_000));
let rate_2 = FeeRate::per_vbyte(Amount::from_sat(10));
assert_eq!(rate_1, rate_2);

assert_eq!(rate_1.as_sat_per_vbyte(), 10.0);
assert_eq!(rate_1.as_btc_per_kvbyte(), 10.0 * 1e3 / 1e8);
}
}

0 comments on commit ad5535d

Please sign in to comment.