Merge rust-bitcoin/rust-bitcoin#4615: Remove reachable unreachable call in psbt

e7c90c57e7 Remove reachable unreachable call in psbt (Tobin C. Harding)
c736e73ae0 Add unwrap_or and unwrap_or_else to NumOpResult (Tobin C. Harding)

Pull request description:

  A bunch of changes have been implemented lately in the fee calculation logic. As a result of this a at once time `unreachable` statement is now reachable - bad rust-bitcoin devs, no biscuit.

  Saturate to `FeeRate::MAX` when calculating the fee rate, check against the limit arg, and win.

  (Patch 1 adds the new combinators to `NumOpResult`. This was pulled out of #4610.)

ACKs for top commit:
  apoelstra:
    ACK e7c90c57e7b5ee20a2c523706cc4ea9957594857; successfully ran local tests

Tree-SHA512: d33b3d5d4442fb17cae4c52880bc5dafdd611d686c6923744bc5f218761e8bff32fc5ab169af9f2ed2f02011516ed850ac8c6bd4ce1d6de40c0ac0b17486bbb4
This commit is contained in:
merge-script 2025-06-13 18:04:41 +00:00
commit 052514e6ff
No known key found for this signature in database
GPG Key ID: C588D63CE41B97C1
2 changed files with 31 additions and 12 deletions

View File

@ -20,7 +20,6 @@ use std::collections::{HashMap, HashSet};
use internals::write_err;
use secp256k1::{Keypair, Message, Secp256k1, Signing, Verification};
use units::NumOpResult;
use crate::bip32::{self, DerivationPath, KeySource, Xpriv, Xpub};
use crate::crypto::key::{PrivateKey, PublicKey};
@ -206,18 +205,12 @@ impl Psbt {
// Note: Move prevents usage of &self from now on.
let tx = self.internal_extract_tx();
// Now that the extracted Transaction is made, decide how to return it.
match fee / tx.weight() {
NumOpResult::Valid(fee_rate) => {
// Prefer to return an AbsurdFeeRate error when both trigger.
if fee_rate > max_fee_rate {
return Err(ExtractTxError::AbsurdFeeRate { fee_rate, tx });
}
}
NumOpResult::Error(_) => unreachable!("weight() is always non-zero"),
let fee_rate = (fee / tx.weight()).unwrap_or(FeeRate::MAX);
if fee_rate > max_fee_rate {
Err(ExtractTxError::AbsurdFeeRate { fee_rate, tx })
} else {
Ok(tx)
}
Ok(tx)
}
/// Combines this [`Psbt`] with `other` PSBT as described by BIP 174.

View File

@ -142,6 +142,32 @@ impl<T: fmt::Debug> NumOpResult<T> {
}
}
/// Returns the contained Some value or a provided default.
///
/// Arguments passed to `unwrap_or` are eagerly evaluated; if you are passing the result of a
/// function call, it is recommended to use `unwrap_or_else`, which is lazily evaluated.
#[inline]
#[track_caller]
pub fn unwrap_or(self, default: T) -> T {
match self {
R::Valid(x) => x,
R::Error(_) => default,
}
}
/// Returns the contained `Some` value or computes it from a closure.
#[inline]
#[track_caller]
pub fn unwrap_or_else<F>(self, f: F) -> T
where
F: FnOnce() -> T,
{
match self {
R::Valid(x) => x,
R::Error(_) => f(),
}
}
/// Converts this `NumOpResult` to an `Option<T>`.
#[inline]
pub fn ok(self) -> Option<T> {