Add fee rate constructors that take Amount as arg

Some users may find it more ergonomic to pass in an `Amount` when
constructing fee rates. Also the strong type adds some semantic meaning
as well as imposes the `Amount::MAX` limit.

Add an equivalent constructor for each of the existing ones that uses an
argument of type `Amount` instead of `u64` sats.
This commit is contained in:
Tobin C. Harding 2025-06-10 09:32:27 +10:00
parent c1a760bf60
commit 6ed3fd6234
No known key found for this signature in database
GPG Key ID: 40BF9E4C269D6607
1 changed files with 31 additions and 0 deletions

View File

@ -11,6 +11,10 @@ use core::ops;
#[cfg(feature = "arbitrary")]
use arbitrary::{Arbitrary, Unstructured};
use NumOpResult as R;
use crate::{Amount,MathOp, NumOpError as E, NumOpResult};
mod encapsulate {
/// Fee rate.
///
@ -62,6 +66,15 @@ impl FeeRate {
}
}
/// Constructs a new [`FeeRate`] from amount per 1000 weight units.
pub const fn from_per_kwu(rate: Amount) -> NumOpResult<Self> {
// No `map()` in const context.
match rate.checked_mul(4_000) {
Some(per_mvb) => R::Valid(FeeRate::from_sat_per_mvb(per_mvb.to_sat())),
None => R::Error(E::while_doing(MathOp::Mul)),
}
}
/// Constructs a new [`FeeRate`] from satoshis per virtual byte,
/// returning `None` if overflow occurred.
pub const fn from_sat_per_vb(sat_vb: u64) -> Option<Self> {
@ -72,6 +85,15 @@ impl FeeRate {
}
}
/// Constructs a new [`FeeRate`] from amount per virtual byte.
pub const fn from_per_vb(rate: Amount) -> NumOpResult<Self> {
// No `map()` in const context.
match rate.checked_mul(1_000_000) {
Some(per_mvb) => R::Valid(FeeRate::from_sat_per_mvb(per_mvb.to_sat())),
None => R::Error(E::while_doing(MathOp::Mul)),
}
}
/// Constructs a new [`FeeRate`] from satoshis per virtual bytes.
pub const fn from_sat_per_vb_u32(sat_vb: u32) -> Self {
let sat_vb = sat_vb as u64; // No `Into` in const context.
@ -88,6 +110,15 @@ impl FeeRate {
}
}
/// Constructs a new [`FeeRate`] from satoshis per kilo virtual bytes (1,000 vbytes).
pub const fn from_per_kvb(rate: Amount) -> NumOpResult<Self> {
// No `map()` in const context.
match rate.checked_mul(1_000) {
Some(per_mvb) => R::Valid(FeeRate::from_sat_per_mvb(per_mvb.to_sat())),
None => R::Error(E::while_doing(MathOp::Mul)),
}
}
/// Converts to sat/kwu rounding down.
pub const fn to_sat_per_kwu_floor(self) -> u64 { self.to_sat_per_mvb() / 4_000 }