Merge rust-bitcoin/rust-bitcoin#4235: Use impl_op_for_references macro in fee module

93c6c8cef5 Use impl_op_for_references macro in fee module (Erick Cestari)

Pull request description:

  This pr replaces the individual operator implementations in the fee module with the impl_op_for_references macro to handle reference operations. This removes the need to manually implement reference combinations for operands, simplifying the code and improving consistency.

  ### Changes:
  - Replaces direct implementations of operators with macro usage
  - Adds tests to verify that reference operations work correctly
  - Maintains the same semantics as the original implementation

  Closes #4173

ACKs for top commit:
  tcharding:
    ACK 93c6c8cef5
  apoelstra:
    ACK 93c6c8cef59ceed56932d62daeb212c2b40fc4a1; successfully ran local tests; yeah, I think the docs loss is fine -- the docs are hard to find and say exactly what users expect of the / operator

Tree-SHA512: 51d7643c2cecd16a0cb16afcd195fd87bc9eca9116e16518d888ba61a8edb5684162af987ea52611c9463f5299810f92a057dedc3fa8e89cdef21ef40528bca1
This commit is contained in:
merge-script 2025-03-13 19:37:59 +00:00
commit 2f711b0c07
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
1 changed files with 41 additions and 33 deletions

View File

@ -159,42 +159,36 @@ impl FeeRate {
}
}
/// Computes the ceiling so that the fee computation is conservative.
impl ops::Mul<FeeRate> for Weight {
crate::internal_macros::impl_op_for_references! {
impl ops::Mul<FeeRate> for Weight {
type Output = NumOpResult<Amount>;
fn mul(self, rhs: FeeRate) -> Self::Output {
rhs.checked_mul_by_weight(self).valid_or_error()
}
}
fn mul(self, rhs: FeeRate) -> Self::Output { rhs.checked_mul_by_weight(self).valid_or_error() }
}
impl ops::Mul<Weight> for FeeRate {
impl ops::Mul<Weight> for FeeRate {
type Output = NumOpResult<Amount>;
fn mul(self, rhs: Weight) -> Self::Output {
self.checked_mul_by_weight(rhs).valid_or_error()
}
}
fn mul(self, rhs: Weight) -> Self::Output { self.checked_mul_by_weight(rhs).valid_or_error() }
}
impl ops::Div<Weight> for Amount {
impl ops::Div<Weight> for Amount {
type Output = FeeRate;
/// Truncating integer division.
///
/// This is likely the wrong thing for a user dividing an amount by a weight. Consider using
/// `checked_div_by_weight` instead.
fn div(self, rhs: Weight) -> Self::Output {
FeeRate::from_sat_per_kwu(self.to_sat() * 1000 / rhs.to_wu())
}
}
}
impl ops::Div<FeeRate> for Amount {
impl ops::Div<FeeRate> for Amount {
type Output = Weight;
/// Truncating integer division.
///
/// # Panics
///
/// This operation will panic if `fee_rate` is zero or the division results in overflow.
///
/// Note: This uses floor division. For ceiling division use [`Amount::checked_div_by_fee_rate_ceil`].
fn div(self, rhs: FeeRate) -> Self::Output { self.checked_div_by_fee_rate_floor(rhs).unwrap() }
fn div(self, rhs: FeeRate) -> Self::Output {
self.checked_div_by_fee_rate_floor(rhs).unwrap()
}
}
}
impl Weight {
@ -265,9 +259,15 @@ mod tests {
let six = Amount::from_sat_unchecked(6);
assert_eq!(two * three, six.into());
// Test reference operators
assert_eq!(&two * three, six.into());
assert_eq!(two * &three, six.into());
assert_eq!(&two * &three, six.into());
}
#[test]
#[allow(clippy::op_ref)]
fn amount_div_by_fee_rate() {
// Test exact division
let amount = Amount::from_sat_unchecked(1000);
@ -275,6 +275,14 @@ mod tests {
let weight = amount / fee_rate;
assert_eq!(weight, Weight::from_wu(500_000));
// Test reference division
let weight_ref = &amount / fee_rate;
assert_eq!(weight_ref, Weight::from_wu(500_000));
let weight_ref2 = amount / &fee_rate;
assert_eq!(weight_ref2, Weight::from_wu(500_000));
let weight_ref3 = &amount / &fee_rate;
assert_eq!(weight_ref3, Weight::from_wu(500_000));
// Test truncation behavior
let amount = Amount::from_sat_unchecked(1000);
let fee_rate = FeeRate::from_sat_per_kwu(3);