Merge rust-bitcoin/rust-bitcoin#1864: Add a checked version of weight mul fee_rate

b03c24db8c Add a checked version of weight mul fee_rate (yancy)

Pull request description:

  Add a checked version of fee_rate * weight.  While I like the trait version of just being able to multiply `feerate * weight`, it's not really very useful imo since a large input feerate could cause an overflow.  Instead of changing the trait in https://github.com/rust-bitcoin/rust-bitcoin/pull/1849 (not idiomatic enough I guess) I added a `checked_weight_mul` method to `FeeRate`.

ACKs for top commit:
  apoelstra:
    ACK b03c24db8c
  Kixunil:
    ACK b03c24db8c

Tree-SHA512: 231ade94291becadcea9ea2a40a5daf96b77f01a29cca2494d7bbe4f7de5b412fa8fc816ea249268569f5378410185d9349fd687533bf3a422a752997e107a2b
This commit is contained in:
Andrew Poelstra 2023-05-22 18:24:43 +00:00
commit 8d111f20ef
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
1 changed files with 18 additions and 0 deletions

View File

@ -79,6 +79,14 @@ impl FeeRate {
/// ///
/// Computes `self / rhs` returning `None` if `rhs == 0`. /// Computes `self / rhs` returning `None` if `rhs == 0`.
pub fn checked_div(self, rhs: u64) -> Option<Self> { self.0.checked_div(rhs).map(Self) } pub fn checked_div(self, rhs: u64) -> Option<Self> { self.0.checked_div(rhs).map(Self) }
/// Checked weight multiplication.
///
/// Computes `self * rhs` where rhs is of type Weight. `None` is returned if an overflow
/// occured.
pub fn checked_mul_by_weight(self, rhs: Weight) -> Option<Amount> {
self.0.checked_mul(rhs.to_wu()).map(Amount::from_sat)
}
} }
/// Alternative will display the unit. /// Alternative will display the unit.
@ -173,6 +181,16 @@ mod tests {
assert!(fee_rate.is_none()); assert!(fee_rate.is_none());
} }
#[test]
fn checked_weight_mul_test() {
let weight = Weight::from_wu(10);
let fee: Amount = FeeRate(10).checked_mul_by_weight(weight).expect("expected Amount");
assert_eq!(Amount::from_sat(100), fee);
let fee = FeeRate(10).checked_mul_by_weight(Weight::MAX);
assert!(fee.is_none());
}
#[test] #[test]
fn checked_div_test() { fn checked_div_test() {
let fee_rate = FeeRate(10).checked_div(10).expect("expected feerate in sat/kwu"); let fee_rate = FeeRate(10).checked_div(10).expect("expected feerate in sat/kwu");