Merge rust-bitcoin/rust-bitcoin#3983: Add symmetrical fee calculation method to Weight

e91cb3ff70 Run just check-api (jrakibi)
134c146748 Add Weight::checked_mul_by_fee_rate method (jrakibi)

Pull request description:

  Following up on #3736, this PR adds `checked_mul_by_fee_rate` to `Weight` to mirror the existing `checked_mul_by_weight` method on `FeeRate`.

  This makes the fee calculation more symmetrical.

  Changes:
  - Add `Weight::checked_mul_by_fee_rate` method
  - Add corresponding test cases

  The new method allows users to calculate fees starting from either Weight or FeeRate. This makes fee calculations more intuitive regardless of which type the user starts with.

  Closes #3766

ACKs for top commit:
  tcharding:
    ACK e91cb3ff70
  apoelstra:
    ACK e91cb3ff7078277f5b173773263863fcaef47ae3; successfully ran local tests

Tree-SHA512: 10d17763a8b04027e0f650a8fb15245671214e46ae13fe0b0a86c2ee8b79c1542e449cb298bf65f2e30b6837de5ae237b221b9c90575a0318959feb64ab95221
This commit is contained in:
merge-script 2025-02-02 23:05:06 +00:00
commit 917149998b
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
4 changed files with 18 additions and 0 deletions

View File

@ -776,6 +776,7 @@ pub const fn bitcoin_units::locktime::relative::Time::value(self) -> u16
pub const fn bitcoin_units::weight::Weight::checked_add(self, rhs: Self) -> core::option::Option<Self>
pub const fn bitcoin_units::weight::Weight::checked_div(self, rhs: u64) -> core::option::Option<Self>
pub const fn bitcoin_units::weight::Weight::checked_mul(self, rhs: u64) -> core::option::Option<Self>
pub const fn bitcoin_units::weight::Weight::checked_mul_by_fee_rate(self, fee_rate: bitcoin_units::fee_rate::FeeRate) -> core::option::Option<bitcoin_units::Amount>
pub const fn bitcoin_units::weight::Weight::checked_sub(self, rhs: Self) -> core::option::Option<Self>
pub const fn bitcoin_units::weight::Weight::from_non_witness_data_size(non_witness_size: u64) -> Self
pub const fn bitcoin_units::weight::Weight::from_vb(vb: u64) -> core::option::Option<Self>

View File

@ -714,6 +714,7 @@ pub const fn bitcoin_units::locktime::relative::Time::value(self) -> u16
pub const fn bitcoin_units::weight::Weight::checked_add(self, rhs: Self) -> core::option::Option<Self>
pub const fn bitcoin_units::weight::Weight::checked_div(self, rhs: u64) -> core::option::Option<Self>
pub const fn bitcoin_units::weight::Weight::checked_mul(self, rhs: u64) -> core::option::Option<Self>
pub const fn bitcoin_units::weight::Weight::checked_mul_by_fee_rate(self, fee_rate: bitcoin_units::fee_rate::FeeRate) -> core::option::Option<bitcoin_units::Amount>
pub const fn bitcoin_units::weight::Weight::checked_sub(self, rhs: Self) -> core::option::Option<Self>
pub const fn bitcoin_units::weight::Weight::from_non_witness_data_size(non_witness_size: u64) -> Self
pub const fn bitcoin_units::weight::Weight::from_vb(vb: u64) -> core::option::Option<Self>

View File

@ -696,6 +696,7 @@ pub const fn bitcoin_units::locktime::relative::Time::value(self) -> u16
pub const fn bitcoin_units::weight::Weight::checked_add(self, rhs: Self) -> core::option::Option<Self>
pub const fn bitcoin_units::weight::Weight::checked_div(self, rhs: u64) -> core::option::Option<Self>
pub const fn bitcoin_units::weight::Weight::checked_mul(self, rhs: u64) -> core::option::Option<Self>
pub const fn bitcoin_units::weight::Weight::checked_mul_by_fee_rate(self, fee_rate: bitcoin_units::fee_rate::FeeRate) -> core::option::Option<bitcoin_units::Amount>
pub const fn bitcoin_units::weight::Weight::checked_sub(self, rhs: Self) -> core::option::Option<Self>
pub const fn bitcoin_units::weight::Weight::from_non_witness_data_size(non_witness_size: u64) -> Self
pub const fn bitcoin_units::weight::Weight::from_vb(vb: u64) -> core::option::Option<Self>

View File

@ -191,6 +191,21 @@ impl ops::Div<FeeRate> for Amount {
fn div(self, rhs: FeeRate) -> Self::Output { self.checked_div_by_fee_rate_floor(rhs).unwrap() }
}
impl Weight {
/// Checked fee rate multiplication.
///
/// Computes the absolute fee amount for a given [`FeeRate`] at this weight.
/// When the resulting fee is a non-integer amount, the amount is rounded up,
/// ensuring that the transaction fee is enough instead of falling short if
/// rounded down.
///
/// [`None`] is returned if an overflow occurred.
#[must_use]
pub const fn checked_mul_by_fee_rate(self, fee_rate: FeeRate) -> Option<Amount> {
fee_rate.checked_mul_by_weight(self)
}
}
#[cfg(test)]
mod tests {
use super::*;