diff --git a/src/lib.rs b/src/lib.rs index a4733df..c28482d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -57,8 +57,9 @@ use core2::io; #[rustfmt::skip] // Keep pubic re-exports separate #[doc(inline)] pub use crate::{ - sighash_type::{PsbtSighashType, InvalidSighashTypeError}, - version::Version, + error::{InconsistentKeySourcesError, FeeError, FundingUtxoError}, + sighash_type::{PsbtSighashType, InvalidSighashTypeError, ParseSighashTypeError}, + version::{Version, UnsupportedVersionError}, }; /// PSBT version 0 - the original PSBT version. diff --git a/src/raw.rs b/src/raw.rs index f1c23d2..70d069d 100644 --- a/src/raw.rs +++ b/src/raw.rs @@ -7,7 +7,7 @@ //! - ` := ` //! - ` := ` //! -//! [BIP-174]: . +//! [BIP-174]: use core::convert::TryFrom; use core::fmt; diff --git a/src/sighash_type.rs b/src/sighash_type.rs index 97e9bb9..7420007 100644 --- a/src/sighash_type.rs +++ b/src/sighash_type.rs @@ -29,7 +29,7 @@ impl fmt::Display for PsbtSighashType { } impl FromStr for PsbtSighashType { - type Err = SighashTypeParseError; + type Err = ParseSighashTypeError; #[inline] fn from_str(s: &str) -> Result { @@ -47,7 +47,7 @@ impl FromStr for PsbtSighashType { return Ok(PsbtSighashType { inner }); } - Err(SighashTypeParseError { unrecognized: s.to_owned() }) + Err(ParseSighashTypeError { unrecognized: s.to_owned() }) } } impl From for PsbtSighashType { @@ -97,19 +97,19 @@ impl PsbtSighashType { /// This is currently returned for unrecognized sighash strings. #[derive(Debug, Clone, PartialEq, Eq)] #[non_exhaustive] -pub struct SighashTypeParseError { +pub struct ParseSighashTypeError { /// The unrecognized string we attempted to parse. pub unrecognized: String, } -impl fmt::Display for SighashTypeParseError { +impl fmt::Display for ParseSighashTypeError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "unrecognized SIGHASH string '{}'", self.unrecognized) } } #[cfg(feature = "std")] -impl std::error::Error for SighashTypeParseError { +impl std::error::Error for ParseSighashTypeError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { None } } diff --git a/src/v0/mod.rs b/src/v0/mod.rs index 9ab2a11..96607d0 100644 --- a/src/v0/mod.rs +++ b/src/v0/mod.rs @@ -36,7 +36,7 @@ pub use self::{ #[rustfmt::skip] // Keep public re-exports separate. #[cfg(feature = "base64")] -pub use self::display_from_str::PsbtParseError; +pub use self::display_from_str::ParsePsbtError; /// Combines these two PSBTs as described by BIP-174. /// @@ -551,27 +551,27 @@ mod display_from_str { } impl FromStr for Psbt { - type Err = PsbtParseError; + type Err = ParsePsbtError; fn from_str(s: &str) -> Result { - let data = BASE64_STANDARD.decode(s).map_err(PsbtParseError::Base64Encoding)?; - Psbt::deserialize(&data).map_err(PsbtParseError::PsbtEncoding) + let data = BASE64_STANDARD.decode(s).map_err(ParsePsbtError::Base64Encoding)?; + Psbt::deserialize(&data).map_err(ParsePsbtError::PsbtEncoding) } } /// Error encountered during PSBT decoding from Base64 string. #[derive(Debug)] #[non_exhaustive] - pub enum PsbtParseError { + pub enum ParsePsbtError { /// Error in internal PSBT data structure. PsbtEncoding(DeserializeError), /// Error in PSBT Base64 encoding. Base64Encoding(bitcoin::base64::DecodeError), } - impl Display for PsbtParseError { + impl Display for ParsePsbtError { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - use self::PsbtParseError::*; + use self::ParsePsbtError::*; match *self { PsbtEncoding(ref e) => write_err!(f, "error in internal PSBT data structure"; e), @@ -581,9 +581,9 @@ mod display_from_str { } #[cfg(feature = "std")] - impl std::error::Error for PsbtParseError { + impl std::error::Error for ParsePsbtError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - use self::PsbtParseError::*; + use self::ParsePsbtError::*; match self { PsbtEncoding(e) => Some(e), diff --git a/src/v2/extract.rs b/src/v2/extract.rs index 36f0ab4..b00cb0d 100644 --- a/src/v2/extract.rs +++ b/src/v2/extract.rs @@ -30,9 +30,9 @@ impl Extractor { /// Creates an `Extractor`. /// /// An extractor can only accept a PSBT that has been finalized. - pub fn new(psbt: Psbt) -> Result { + pub fn new(psbt: Psbt) -> Result { if psbt.inputs.iter().any(|input| !input.is_finalized()) { - return Err(Error::PsbtNotFinalized); + return Err(ExtractError::PsbtNotFinalized); } let _ = psbt.determine_lock_time()?; @@ -124,18 +124,18 @@ impl Extractor { } } -/// Error constructing a [`Finalizer`]. +/// Error constructing an `Extractor`. #[derive(Debug)] -pub enum Error { +pub enum ExtractError { /// Attempted to extract tx from an unfinalized PSBT. PsbtNotFinalized, /// Finalizer must be able to determine the lock time. DetermineLockTime(DetermineLockTimeError), } -impl fmt::Display for Error { +impl fmt::Display for ExtractError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - use Error::*; + use ExtractError::*; match *self { PsbtNotFinalized => write!(f, "attempted to extract tx from an unfinalized PSBT"), @@ -146,9 +146,9 @@ impl fmt::Display for Error { } #[cfg(feature = "std")] -impl std::error::Error for Error { +impl std::error::Error for ExtractError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - use Error::*; + use ExtractError::*; match *self { DetermineLockTime(ref e) => Some(e), @@ -157,7 +157,7 @@ impl std::error::Error for Error { } } -impl From for Error { +impl From for ExtractError { fn from(e: DetermineLockTimeError) -> Self { Self::DetermineLockTime(e) } } diff --git a/src/v2/map/global.rs b/src/v2/map/global.rs index 8038962..cedd747 100644 --- a/src/v2/map/global.rs +++ b/src/v2/map/global.rs @@ -468,6 +468,7 @@ impl Map for Global { } } +/// An error while decoding. #[derive(Debug)] #[non_exhaustive] pub enum DecodeError { @@ -560,7 +561,10 @@ pub enum InsertPairError { /// PSBT_GLOBAL_PROPRIETARY: Invalid proprietary key. InvalidProprietaryKey, /// Key must be excluded from this version of PSBT (see consts.rs for u8 values). - ExcludedKey { key_type_value: u8 }, + ExcludedKey { + /// Key type value we found. + key_type_value: u8, + }, } impl fmt::Display for InsertPairError { diff --git a/src/v2/map/input.rs b/src/v2/map/input.rs index c359df4..5a42d96 100644 --- a/src/v2/map/input.rs +++ b/src/v2/map/input.rs @@ -783,6 +783,7 @@ impl InputBuilder { pub fn build(self) -> Input { self.0 } } +/// An error while decoding. #[derive(Debug)] #[non_exhaustive] pub enum DecodeError { diff --git a/src/v2/map/mod.rs b/src/v2/map/mod.rs index f3cbd31..008664a 100644 --- a/src/v2/map/mod.rs +++ b/src/v2/map/mod.rs @@ -1,21 +1,25 @@ // SPDX-License-Identifier: CC0-1.0 -// TODO: These are pubic just so we can write global::DecodeError, is that a good choice? +//! Implementation of the "maps" concept defined in BIP-174. +//! +//! > The Partially Signed Bitcoin Transaction (PSBT) format consists of key-value maps. +//! > ... +//! > ` := * 0x00` +//! > ` := * 0x00` +//! > ` := * 0x00` +//! > ... + +/// The `global-map`. pub mod global; +/// The `input-map`. pub mod input; +/// The `output-map`. pub mod output; use crate::prelude::*; use crate::raw; use crate::serialize::Serialize; -#[rustfmt::skip] // Keep pubic re-exports separate -pub use self::{ - input::{Input, InputBuilder}, - output::{Output, OutputBuilder}, - global::Global, -}; - /// A trait that describes a PSBT key-value map. pub(crate) trait Map { /// Attempt to get all key-value pairs. diff --git a/src/v2/map/output.rs b/src/v2/map/output.rs index af1af9d..7acb5ba 100644 --- a/src/v2/map/output.rs +++ b/src/v2/map/output.rs @@ -272,6 +272,7 @@ impl OutputBuilder { pub fn build(self) -> Output { self.0 } } +/// An error while decoding. #[derive(Debug)] #[non_exhaustive] pub enum DecodeError { diff --git a/src/v2/miniscript/mod.rs b/src/v2/miniscript/mod.rs index ebc5f6d..7935bd1 100644 --- a/src/v2/miniscript/mod.rs +++ b/src/v2/miniscript/mod.rs @@ -32,11 +32,11 @@ use miniscript::{interpreter, Interpreter, MiniscriptKey}; use crate::error::write_err; use crate::prelude::*; -use crate::v2::map::Input; +use crate::v2::map::input::Input; use crate::v2::{DetermineLockTimeError, Psbt}; #[rustfmt::skip] // Keep public exports separate. -pub use self::finalize::{Finalizer, InputError, FinalizeError, FinalizeInputError}; +pub use self::finalize::{InputError, Finalizer, FinalizeError, FinalizeInputError}; impl Psbt { // TODO: Should this be on a Role? Finalizer/Extractor? Then we can remove the debug_assert @@ -186,9 +186,19 @@ impl From for InterpreterCheckError { #[derive(Debug)] pub enum InterpreterCheckInputError { /// Failed to construct a [`miniscript::Interpreter`]. - Constructor { input_index: usize, error: interpreter::Error }, + Constructor { + /// Index of the input causing this error. + input_index: usize, + /// The interpreter error returned from `rust-miniscript`. + error: interpreter::Error, + }, /// Interpreter satisfaction failed for input. - Satisfaction { input_index: usize, error: interpreter::Error }, + Satisfaction { + /// Index of the input causing this error. + input_index: usize, + /// The interpreter error returned from `rust-miniscript`. + error: interpreter::Error, + }, } impl fmt::Display for InterpreterCheckInputError { diff --git a/src/v2/miniscript/satisfy.rs b/src/v2/miniscript/satisfy.rs index 5e1394b..8f531cc 100644 --- a/src/v2/miniscript/satisfy.rs +++ b/src/v2/miniscript/satisfy.rs @@ -14,7 +14,7 @@ use crate::v2::map::input::Input; /// operations on this structure will panic if index is more than number of inputs in pbst /// /// [`Satisfier`]: crate::miniscript::Satisfier -pub struct InputSatisfier<'a> { +pub(crate) struct InputSatisfier<'a> { pub(crate) input: &'a Input, } diff --git a/src/v2/mod.rs b/src/v2/mod.rs index 69cc251..fd12afe 100644 --- a/src/v2/mod.rs +++ b/src/v2/mod.rs @@ -45,19 +45,31 @@ use bitcoin::{ecdsa, transaction, Amount, Sequence, Transaction, TxOut, Txid}; use crate::error::{write_err, FeeError, FundingUtxoError}; use crate::prelude::*; use crate::v0; -use crate::v2::map::{global, input, output, Map}; +use crate::v2::map::Map; #[rustfmt::skip] // Keep public exports separate. #[doc(inline)] pub use self::{ - error::{IndexOutOfBoundsError, SignError, PsbtNotModifiableError, NotUnsignedError, OutputsNotModifiableError, InputsNotModifiableError, DetermineLockTimeError, DeserializeError, PartialSigsSighashTypeError}, - map::{Input, InputBuilder, Output, OutputBuilder, Global}, - extract::{ExtractTxError, ExtractTxFeeRateError, Extractor} + error::{ + DeserializeError, DetermineLockTimeError, IndexOutOfBoundsError, InputsNotModifiableError, + NotUnsignedError, OutputsNotModifiableError, PartialSigsSighashTypeError, + PsbtNotModifiableError, SignError, + }, + extract::{Extractor, ExtractError, ExtractTxError, ExtractTxFeeRateError}, + map::{ + // We do not re-export any of the input/output/global error types, use form `input::DecodeError`. + global::{self, Global}, + input::{self, Input, InputBuilder}, + output::{self, Output, OutputBuilder}, + }, }; #[cfg(feature = "base64")] -pub use self::display_from_str::PsbtParseError; +pub use self::display_from_str::ParsePsbtError; #[cfg(feature = "miniscript")] -pub use self::miniscript::{FinalizeError, FinalizeInputError, Finalizer, InputError}; +pub use self::miniscript::{ + FinalizeError, FinalizeInputError, Finalizer, InputError, InterpreterCheckError, + InterpreterCheckInputError, +}; /// Combines these two PSBTs as described by BIP-174 (i.e. combine is the same for BIP-370). /// @@ -955,7 +967,9 @@ impl Psbt { /// /// This can be used at anytime but is primarily used during PSBT finalizing. #[cfg(feature = "miniscript")] - pub(crate) fn check_partial_sigs_sighash_type(&self) -> Result<(), PartialSigsSighashTypeError> { + pub(crate) fn check_partial_sigs_sighash_type( + &self, + ) -> Result<(), PartialSigsSighashTypeError> { use PartialSigsSighashTypeError::*; for (input_index, input) in self.inputs.iter().enumerate() { @@ -1254,27 +1268,27 @@ mod display_from_str { } impl FromStr for Psbt { - type Err = PsbtParseError; + type Err = ParsePsbtError; fn from_str(s: &str) -> Result { - let data = BASE64_STANDARD.decode(s).map_err(PsbtParseError::Base64Encoding)?; - Psbt::deserialize(&data).map_err(PsbtParseError::PsbtEncoding) + let data = BASE64_STANDARD.decode(s).map_err(ParsePsbtError::Base64Encoding)?; + Psbt::deserialize(&data).map_err(ParsePsbtError::PsbtEncoding) } } /// Error encountered during PSBT decoding from Base64 string. #[derive(Debug)] #[non_exhaustive] - pub enum PsbtParseError { + pub enum ParsePsbtError { /// Error in internal PSBT data structure. PsbtEncoding(DeserializeError), /// Error in PSBT Base64 encoding. Base64Encoding(bitcoin::base64::DecodeError), } - impl Display for PsbtParseError { + impl Display for ParsePsbtError { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - use self::PsbtParseError::*; + use self::ParsePsbtError::*; match *self { PsbtEncoding(ref e) => write_err!(f, "error in internal PSBT data structure"; e), @@ -1284,9 +1298,9 @@ mod display_from_str { } #[cfg(feature = "std")] - impl std::error::Error for PsbtParseError { + impl std::error::Error for ParsePsbtError { fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - use self::PsbtParseError::*; + use self::ParsePsbtError::*; match self { PsbtEncoding(e) => Some(e),