Merge rust-bitcoin/rust-bitcoin#4472: Change the return type of effective_value

b038520c4d Change the return type of effective_value (yancy)

Pull request description:

  Prefer the more informative return type NumOpResult over Option.  Also a returns section was added which describes the different possible returns.

  The api of NumOpResult could probably be extended to cleanup the match statement.  Also consider api addition for unchecked calculations natively.

ACKs for top commit:
  tcharding:
    ACK b038520c4d
  apoelstra:
    ACK b038520c4dc8c2f92cb40a9fd272608ae2e9b799; successfully ran local tests

Tree-SHA512: 2e66a3ca83514f0ad011660178f8e5ea9d9b1de03dc030e7c57f558e08a42261724251364bb7a746b6970b4288a45539a33d3b36b114c855b6246a56fee3c61c
This commit is contained in:
merge-script 2025-05-12 15:53:49 +00:00
commit a8e85b61aa
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
1 changed files with 15 additions and 4 deletions

View File

@ -27,6 +27,7 @@ use crate::script::{Script, ScriptBuf, ScriptExt as _, ScriptExtPriv as _};
use crate::sighash::{EcdsaSighashType, TapSighashType};
use crate::witness::Witness;
use crate::{Amount, FeeRate, SignedAmount};
use units::NumOpResult;
#[rustfmt::skip] // Keep public re-exports separate.
#[doc(inline)]
@ -773,14 +774,24 @@ impl Decodable for Transaction {
///
/// * `fee_rate` - the fee rate of the transaction being created.
/// * `input_weight_prediction` - the predicted input weight.
///
/// # Returns
///
/// This will return [`NumOpResult::Error`] if the fee calculation (fee_rate * weight) overflows.
/// Otherwise, [`NumOpResult::Valid`] will wrap the successful calculation.
pub fn effective_value(
fee_rate: FeeRate,
input_weight_prediction: InputWeightPrediction,
value: Amount,
) -> Option<SignedAmount> {
) -> NumOpResult<SignedAmount> {
let weight = input_weight_prediction.total_weight();
let signed_input_fee = fee_rate.to_fee(weight).ok()?.to_signed();
value.to_signed().checked_sub(signed_input_fee)
let fee = match fee_rate.to_fee(weight) {
NumOpResult::Valid(x) => x.to_signed(),
NumOpResult::Error(e) => return NumOpResult::Error(e)
};
value.to_signed() - fee // Cannot overflow.
}
/// Predicts the weight of a to-be-constructed transaction.
@ -1665,7 +1676,7 @@ mod tests {
fn effective_value_fee_rate_does_not_overflow() {
let eff_value =
effective_value(FeeRate::MAX, InputWeightPrediction::P2WPKH_MAX, Amount::ZERO);
assert!(eff_value.is_none());
assert!(eff_value.is_error());
}
#[test]