Add checked weight division to Amount
This commit is contained in:
parent
8def40a991
commit
a0c58a4a8b
|
@ -5,6 +5,9 @@
|
||||||
//! This module mainly introduces the [`Amount`] and [`SignedAmount`] types.
|
//! This module mainly introduces the [`Amount`] and [`SignedAmount`] types.
|
||||||
//! We refer to the documentation on the types for more information.
|
//! We refer to the documentation on the types for more information.
|
||||||
|
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
|
use crate::{Weight, FeeRate};
|
||||||
|
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
use alloc::string::{String, ToString};
|
use alloc::string::{String, ToString};
|
||||||
use core::cmp::Ordering;
|
use core::cmp::Ordering;
|
||||||
|
@ -1039,6 +1042,22 @@ impl Amount {
|
||||||
/// Returns [`None`] if overflow occurred.
|
/// Returns [`None`] if overflow occurred.
|
||||||
pub fn checked_div(self, rhs: u64) -> Option<Amount> { self.0.checked_div(rhs).map(Amount) }
|
pub fn checked_div(self, rhs: u64) -> Option<Amount> { self.0.checked_div(rhs).map(Amount) }
|
||||||
|
|
||||||
|
/// Checked weight division.
|
||||||
|
///
|
||||||
|
/// Be aware that integer division loses the remainder if no exact division
|
||||||
|
/// can be made. This method rounds up ensuring the transaction fee-rate is
|
||||||
|
/// sufficient. If you wish to round-down, use the unchecked version instead.
|
||||||
|
///
|
||||||
|
/// [`None`] is returned if an overflow occurred.
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
|
pub fn checked_div_by_weight(self, rhs: Weight) -> Option<FeeRate> {
|
||||||
|
let sats = self.0.checked_mul(1000)?;
|
||||||
|
let wu = rhs.to_wu();
|
||||||
|
|
||||||
|
let fee_rate = sats.checked_add(wu.checked_sub(1)?)?.checked_div(wu)?;
|
||||||
|
Some(FeeRate::from_sat_per_kwu(fee_rate))
|
||||||
|
}
|
||||||
|
|
||||||
/// Checked remainder.
|
/// Checked remainder.
|
||||||
///
|
///
|
||||||
/// Returns [`None`] if overflow occurred.
|
/// Returns [`None`] if overflow occurred.
|
||||||
|
@ -2219,6 +2238,31 @@ mod tests {
|
||||||
assert_eq!(ssat(-6).checked_div(2), Some(ssat(-3)));
|
assert_eq!(ssat(-6).checked_div(2), Some(ssat(-3)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "alloc")]
|
||||||
|
#[test]
|
||||||
|
fn amount_checked_div_by_weight() {
|
||||||
|
let weight = Weight::from_kwu(1).unwrap();
|
||||||
|
let fee_rate = Amount::from_sat(1)
|
||||||
|
.checked_div_by_weight(weight)
|
||||||
|
.unwrap();
|
||||||
|
// 1 sats / 1,000 wu = 1 sats/kwu
|
||||||
|
assert_eq!(fee_rate, FeeRate::from_sat_per_kwu(1));
|
||||||
|
|
||||||
|
let weight = Weight::from_wu(381);
|
||||||
|
let fee_rate = Amount::from_sat(329)
|
||||||
|
.checked_div_by_weight(weight)
|
||||||
|
.unwrap();
|
||||||
|
// 329 sats / 381 wu = 863.5 sats/kwu
|
||||||
|
// round up to 864
|
||||||
|
assert_eq!(fee_rate, FeeRate::from_sat_per_kwu(864));
|
||||||
|
|
||||||
|
let fee_rate = Amount::MAX.checked_div_by_weight(weight);
|
||||||
|
assert!(fee_rate.is_none());
|
||||||
|
|
||||||
|
let fee_rate = Amount::ONE_SAT.checked_div_by_weight(Weight::ZERO);
|
||||||
|
assert!(fee_rate.is_none());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
#[cfg(not(debug_assertions))]
|
#[cfg(not(debug_assertions))]
|
||||||
fn unchecked_amount_add() {
|
fn unchecked_amount_add() {
|
||||||
|
|
Loading…
Reference in New Issue