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 dfbe771
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 29 deletions.
17 changes: 7 additions & 10 deletions integration_test/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ use bitcoin::hashes::hex::{FromHex, ToHex};
use bitcoin::hashes::Hash;
use bitcoin::secp256k1;
use bitcoin::{
Address, Amount, Network, OutPoint, PrivateKey, Script, EcdsaSighashType, SignedAmount, Transaction,
TxIn, TxOut, Txid, Witness,
Address, Amount, EcdsaSighashType, Network, OutPoint, PrivateKey, Script, SignedAmount,
Transaction, TxIn, TxOut, Txid, Witness,
};
use bitcoincore_rpc::bitcoincore_rpc_json::{
GetBlockTemplateModes, GetBlockTemplateRules, ScanTxOutRequest,
Expand Down Expand Up @@ -597,8 +597,9 @@ fn test_sign_raw_transaction_with_send_raw_transaction(cl: &Client) {
}],
};

let res =
cl.sign_raw_transaction_with_key(&tx, &[sk], None, Some(EcdsaSighashType::All.into())).unwrap();
let res = cl
.sign_raw_transaction_with_key(&tx, &[sk], None, Some(EcdsaSighashType::All.into()))
.unwrap();
assert!(res.complete);
let _ = cl.send_raw_transaction(&res.transaction().unwrap()).unwrap();
}
Expand Down Expand Up @@ -687,7 +688,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 Expand Up @@ -1103,11 +1104,7 @@ fn test_add_ban(cl: &Client) {
let res = cl.list_banned().unwrap();
assert_eq!(res.len(), 0);

assert_error_message!(
cl.add_ban("INVALID_STRING", 0, false),
-30,
"Error: Invalid IP/Subnet"
);
assert_error_message!(cl.add_ban("INVALID_STRING", 0, false), -30, "Error: Invalid IP/Subnet");
}

fn test_set_network_active(cl: &Client) {
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 dfbe771

Please sign in to comment.