Skip to content

Commit

Permalink
Make pub PsbtInputError with internal variants
Browse files Browse the repository at this point in the history
The internal variants aren't yet stable, so we use the InternalError
pattern to hide them, and make internal variants pub(crate).
  • Loading branch information
DanGould committed Oct 30, 2024
1 parent 241e2ba commit bd15da7
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 17 deletions.
46 changes: 32 additions & 14 deletions payjoin/src/psbt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,13 @@ impl<'a> InternalInputPair<'a> {
}
}

pub fn validate_utxo(&self, treat_missing_as_error: bool) -> Result<(), PsbtInputError> {
pub fn validate_utxo(
&self,
treat_missing_as_error: bool,
) -> Result<(), InternalPsbtInputError> {
match (&self.psbtin.non_witness_utxo, &self.psbtin.witness_utxo) {
(None, None) if treat_missing_as_error =>
Err(PsbtInputError::PrevTxOut(PrevTxOutError::MissingUtxoInformation)),
Err(InternalPsbtInputError::PrevTxOut(PrevTxOutError::MissingUtxoInformation)),
(None, None) => Ok(()),
(Some(tx), None) if tx.compute_txid() == self.txin.previous_output.txid => tx
.output
Expand All @@ -154,7 +157,7 @@ impl<'a> InternalInputPair<'a> {
.into()
})
.map(drop),
(Some(_), None) => Err(PsbtInputError::UnequalTxid),
(Some(_), None) => Err(InternalPsbtInputError::UnequalTxid),
(None, Some(_)) => Ok(()),
(Some(tx), Some(witness_txout))
if tx.compute_txid() == self.txin.previous_output.txid =>
Expand All @@ -174,10 +177,10 @@ impl<'a> InternalInputPair<'a> {
if witness_txout == non_witness_txout {
Ok(())
} else {
Err(PsbtInputError::SegWitTxOutMismatch)
Err(InternalPsbtInputError::SegWitTxOutMismatch)
}
}
(Some(_), Some(_)) => Err(PsbtInputError::UnequalTxid),
(Some(_), Some(_)) => Err(InternalPsbtInputError::UnequalTxid),
}
}

Expand Down Expand Up @@ -227,7 +230,7 @@ impl<'a> InternalInputPair<'a> {
}

#[derive(Debug)]
pub enum PrevTxOutError {
pub(crate) enum PrevTxOutError {
MissingUtxoInformation,
IndexOutOfBounds { output_count: usize, index: u32 },
}
Expand All @@ -246,7 +249,7 @@ impl fmt::Display for PrevTxOutError {
impl std::error::Error for PrevTxOutError {}

#[derive(Debug)]
pub enum PsbtInputError {
pub(crate) enum InternalPsbtInputError {
PrevTxOut(PrevTxOutError),
UnequalTxid,
/// TxOut provided in `segwit_utxo` doesn't match the one in `non_segwit_utxo`
Expand All @@ -255,7 +258,7 @@ pub enum PsbtInputError {
NoRedeemScript,
}

impl fmt::Display for PsbtInputError {
impl fmt::Display for InternalPsbtInputError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::PrevTxOut(_) => write!(f, "invalid previous transaction output"),
Expand All @@ -267,7 +270,7 @@ impl fmt::Display for PsbtInputError {
}
}

impl std::error::Error for PsbtInputError {
impl std::error::Error for InternalPsbtInputError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::PrevTxOut(error) => Some(error),
Expand All @@ -279,18 +282,33 @@ impl std::error::Error for PsbtInputError {
}
}

impl From<PrevTxOutError> for PsbtInputError {
fn from(value: PrevTxOutError) -> Self { PsbtInputError::PrevTxOut(value) }
impl From<PrevTxOutError> for InternalPsbtInputError {
fn from(value: PrevTxOutError) -> Self { InternalPsbtInputError::PrevTxOut(value) }
}

impl From<AddressTypeError> for PsbtInputError {
impl From<AddressTypeError> for InternalPsbtInputError {
fn from(value: AddressTypeError) -> Self { Self::AddressType(value) }
}

#[derive(Debug)]
pub struct PsbtInputError(crate::psbt::InternalPsbtInputError);

impl From<crate::psbt::InternalPsbtInputError> for PsbtInputError {
fn from(e: crate::psbt::InternalPsbtInputError) -> Self { PsbtInputError(e) }
}

impl fmt::Display for PsbtInputError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.0) }
}

impl std::error::Error for PsbtInputError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { Some(&self.0) }
}

#[derive(Debug)]
pub struct PsbtInputsError {
index: usize,
error: PsbtInputError,
error: InternalPsbtInputError,
}

impl fmt::Display for PsbtInputsError {
Expand All @@ -304,7 +322,7 @@ impl std::error::Error for PsbtInputsError {
}

#[derive(Debug)]
pub enum AddressTypeError {
pub(crate) enum AddressTypeError {
PrevTxOut(PrevTxOutError),
InvalidScript(FromScriptError),
UnknownAddressType,
Expand Down
7 changes: 7 additions & 0 deletions payjoin/src/receive/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ impl From<crate::ohttp::OhttpEncapsulationError> for Error {
fn from(e: crate::ohttp::OhttpEncapsulationError) -> Self { Error::Server(Box::new(e)) }
}

#[derive(Debug)]
pub struct PsbtInputError(crate::psbt::InternalPsbtInputError);

impl From<crate::psbt::InternalPsbtInputError> for PsbtInputError {
fn from(e: crate::psbt::InternalPsbtInputError) -> Self { PsbtInputError(e) }
}

/// Error that may occur when the request from sender is malformed.
///
/// This is currently opaque type because we aren't sure which variants will stay.
Expand Down
7 changes: 4 additions & 3 deletions payjoin/src/receive/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ use error::{
};
use optional_parameters::Params;

use crate::psbt::{InternalInputPair, PsbtExt, PsbtInputError};
pub use crate::psbt::PsbtInputError;
use crate::psbt::{InternalInputPair, InternalPsbtInputError, PsbtExt};

pub trait Headers {
fn get_header(&self, key: &str) -> Option<&str>;
Expand All @@ -66,9 +67,9 @@ impl InputPair {
let input_pair = Self { txin, psbtin };
let raw = InternalInputPair::from(&input_pair);
raw.validate_utxo(true)?;
let address_type = raw.address_type()?;
let address_type = raw.address_type().map_err(InternalPsbtInputError::AddressType)?;
if address_type == AddressType::P2sh && input_pair.psbtin.redeem_script.is_none() {
return Err(PsbtInputError::NoRedeemScript);
return Err(InternalPsbtInputError::NoRedeemScript.into());
}
Ok(input_pair)
}
Expand Down

0 comments on commit bd15da7

Please sign in to comment.