From bd15da78742d654e0c11dcc99d4b685a40fb338d Mon Sep 17 00:00:00 2001 From: DanGould Date: Wed, 30 Oct 2024 19:14:38 -0400 Subject: [PATCH] Make pub PsbtInputError with internal variants The internal variants aren't yet stable, so we use the InternalError pattern to hide them, and make internal variants pub(crate). --- payjoin/src/psbt.rs | 46 +++++++++++++++++++++++++----------- payjoin/src/receive/error.rs | 7 ++++++ payjoin/src/receive/mod.rs | 7 +++--- 3 files changed, 43 insertions(+), 17 deletions(-) diff --git a/payjoin/src/psbt.rs b/payjoin/src/psbt.rs index 520a3df2..5c012601 100644 --- a/payjoin/src/psbt.rs +++ b/payjoin/src/psbt.rs @@ -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 @@ -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 => @@ -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), } } @@ -227,7 +230,7 @@ impl<'a> InternalInputPair<'a> { } #[derive(Debug)] -pub enum PrevTxOutError { +pub(crate) enum PrevTxOutError { MissingUtxoInformation, IndexOutOfBounds { output_count: usize, index: u32 }, } @@ -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` @@ -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"), @@ -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), @@ -279,18 +282,33 @@ impl std::error::Error for PsbtInputError { } } -impl From for PsbtInputError { - fn from(value: PrevTxOutError) -> Self { PsbtInputError::PrevTxOut(value) } +impl From for InternalPsbtInputError { + fn from(value: PrevTxOutError) -> Self { InternalPsbtInputError::PrevTxOut(value) } } -impl From for PsbtInputError { +impl From for InternalPsbtInputError { fn from(value: AddressTypeError) -> Self { Self::AddressType(value) } } +#[derive(Debug)] +pub struct PsbtInputError(crate::psbt::InternalPsbtInputError); + +impl From 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 { @@ -304,7 +322,7 @@ impl std::error::Error for PsbtInputsError { } #[derive(Debug)] -pub enum AddressTypeError { +pub(crate) enum AddressTypeError { PrevTxOut(PrevTxOutError), InvalidScript(FromScriptError), UnknownAddressType, diff --git a/payjoin/src/receive/error.rs b/payjoin/src/receive/error.rs index 08e90ede..59b8a87d 100644 --- a/payjoin/src/receive/error.rs +++ b/payjoin/src/receive/error.rs @@ -45,6 +45,13 @@ impl From for Error { fn from(e: crate::ohttp::OhttpEncapsulationError) -> Self { Error::Server(Box::new(e)) } } +#[derive(Debug)] +pub struct PsbtInputError(crate::psbt::InternalPsbtInputError); + +impl From 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. diff --git a/payjoin/src/receive/mod.rs b/payjoin/src/receive/mod.rs index 263043a6..a7cad41a 100644 --- a/payjoin/src/receive/mod.rs +++ b/payjoin/src/receive/mod.rs @@ -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>; @@ -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) }