[wallet] Add a type convert fee units, add Wallet::estimate_fee()

This commit is contained in:
Alekos Filini
2020-08-07 11:23:01 +02:00
parent 5f80950971
commit 08792b2fcd
8 changed files with 115 additions and 16 deletions

View File

@@ -22,8 +22,8 @@ pub mod time;
pub mod tx_builder;
pub mod utils;
pub use tx_builder::TxBuilder;
use utils::IsDust;
use tx_builder::TxBuilder;
use utils::{FeeRate, IsDust};
use crate::blockchain::{noop_progress, Blockchain, OfflineBlockchain, OnlineBlockchain};
use crate::database::{BatchDatabase, BatchOperations, DatabaseUtils};
@@ -142,7 +142,7 @@ where
output: vec![],
};
let fee_rate = builder.fee_perkb.unwrap_or(1e3) * 100_000.0;
let fee_rate = builder.fee_rate.unwrap_or_default().as_sat_vb();
if builder.send_all && builder.addressees.len() != 1 {
return Err(Error::SendAllMultipleOutputs);
}
@@ -759,6 +759,11 @@ where
Ok(tx.txid())
}
#[maybe_async]
pub fn estimate_fee(&self, target: usize) -> Result<FeeRate, Error> {
Ok(maybe_await!(self.client.estimate_fee(target))?)
}
}
#[cfg(test)]

View File

@@ -3,13 +3,14 @@ use std::collections::BTreeMap;
use bitcoin::{Address, OutPoint, SigHashType};
use super::coin_selection::{CoinSelectionAlgorithm, DefaultCoinSelectionAlgorithm};
use super::utils::FeeRate;
// TODO: add a flag to ignore change outputs (make them unspendable)
#[derive(Debug, Default)]
pub struct TxBuilder<Cs: CoinSelectionAlgorithm> {
pub(crate) addressees: Vec<(Address, u64)>,
pub(crate) send_all: bool,
pub(crate) fee_perkb: Option<f32>,
pub(crate) fee_rate: Option<FeeRate>,
pub(crate) policy_path: Option<BTreeMap<String, Vec<usize>>>,
pub(crate) utxos: Option<Vec<OutPoint>>,
pub(crate) unspendable: Option<Vec<OutPoint>>,
@@ -44,13 +45,8 @@ impl<Cs: CoinSelectionAlgorithm> TxBuilder<Cs> {
self
}
pub fn fee_rate(mut self, satoshi_per_vbyte: f32) -> Self {
self.fee_perkb = Some(satoshi_per_vbyte * 1e3);
self
}
pub fn fee_rate_perkb(mut self, satoshi_per_kb: f32) -> Self {
self.fee_perkb = Some(satoshi_per_kb);
pub fn fee_rate(mut self, fee_rate: FeeRate) -> Self {
self.fee_rate = Some(fee_rate);
self
}
@@ -93,7 +89,7 @@ impl<Cs: CoinSelectionAlgorithm> TxBuilder<Cs> {
TxBuilder {
addressees: self.addressees,
send_all: self.send_all,
fee_perkb: self.fee_perkb,
fee_rate: self.fee_rate,
policy_path: self.policy_path,
utxos: self.utxos,
unspendable: self.unspendable,

View File

@@ -14,6 +14,34 @@ impl IsDust for u64 {
}
}
#[derive(Debug, Copy, Clone)]
// Internally stored as satoshi/vbyte
pub struct FeeRate(f32);
impl FeeRate {
pub fn from_btc_per_kvb(btc_per_kvb: f32) -> Self {
FeeRate(btc_per_kvb * 1e5)
}
pub fn from_sat_per_vb(sat_per_vb: f32) -> Self {
FeeRate(sat_per_vb)
}
pub fn default_min_relay_fee() -> Self {
FeeRate(1.0)
}
pub fn as_sat_vb(&self) -> f32 {
self.0
}
}
impl std::default::Default for FeeRate {
fn default() -> Self {
FeeRate::default_min_relay_fee()
}
}
pub struct ChunksIterator<I: Iterator> {
iter: I,
size: usize,
@@ -46,3 +74,26 @@ impl<I: Iterator> Iterator for ChunksIterator<I> {
Some(v)
}
}
#[cfg(test)]
mod test {
use super::*;
#[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);
}
}