Skip to content

Commit

Permalink
Improving PSBT FromStr error type
Browse files Browse the repository at this point in the history
  • Loading branch information
dr-orlovsky committed Feb 21, 2021
1 parent fc006bb commit f92f164
Showing 1 changed file with 36 additions and 6 deletions.
42 changes: 36 additions & 6 deletions src/util/psbt/mod.rs
Expand Up @@ -20,7 +20,7 @@

use blockdata::script::Script;
use blockdata::transaction::Transaction;
use consensus::{encode, Encodable, Decodable};
use consensus::{encode, Encodable, Decodable, self};

use std::io;

Expand Down Expand Up @@ -91,25 +91,47 @@ impl PartiallySignedTransaction {
}
}

/// Error happening during PSBT decoding from Base64 string
#[cfg(feature = "base64")]
#[derive(Debug)]
pub enum PsbtParseError {
/// Error in internal PSBT data structure
PsbtEncoding(consensus::encode::Error),
/// Error in PSBT Base64 encoding
Base64Encoding(::base64::DecodeError)
}

#[cfg(feature = "base64")]
mod _base64encoding {
use super::{PartiallySignedTransaction, Error};
use super::{PartiallySignedTransaction, PsbtParseError};
use std::fmt::{Display, Formatter, self};
use std::str::FromStr;
use consensus::encode;
use ::base64::display::Base64Display;

impl Display for PsbtParseError {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
PsbtParseError::PsbtEncoding(err) => Display::fmt(err, f),
PsbtParseError::Base64Encoding(err) => Display::fmt(err, f),
}
}
}

impl std::error::Error for PsbtParseError { }

impl Display for PartiallySignedTransaction {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{}", Base64Display::with_config(&encode::serialize(self), ::base64::STANDARD))
}
}

impl FromStr for PartiallySignedTransaction {
type Err = Error;
type Err = PsbtParseError;

fn from_str(s: &str) -> Result<Self, Self::Err> {
Ok(encode::deserialize(&::base64::decode(s).map_err(|_| Error::ConsensusEncoding)?)?)
let data = ::base64::decode(s).map_err(PsbtParseError::Base64Encoding)?;
Ok(encode::deserialize(&data).map_err(PsbtParseError::PsbtEncoding)?)
}
}
}
Expand Down Expand Up @@ -449,7 +471,7 @@ mod tests {
use blockdata::transaction::{SigHashType, Transaction, TxIn, TxOut, OutPoint};
use consensus::encode::serialize_hex;
use util::psbt::map::{Map, Global, Input, Output};
use util::psbt::raw;
use util::psbt::{raw, PsbtParseError};
use util::psbt::{PartiallySignedTransaction, Error};

#[test]
Expand All @@ -469,6 +491,7 @@ mod tests {
#[should_panic(expected = "ConsensusEncoding")]
fn invalid_vector_2() {
hex_psbt!("70736274ff0100750200000001268171371edff285e937adeea4b37b78000c0566cbb3ad64641713ca42171bf60000000000feffffff02d3dff505000000001976a914d0c59903c5bac2868760e90fd521a4665aa7652088ac00e1f5050000000017a9143545e6e33b832c47050f24d3eeb93c9c03948bc787b32e1300000100fda5010100000000010289a3c71eab4d20e0371bbba4cc698fa295c9463afa2e397f8533ccb62f9567e50100000017160014be18d152a9b012039daf3da7de4f53349eecb985ffffffff86f8aa43a71dff1448893a530a7237ef6b4608bbb2dd2d0171e63aec6a4890b40100000017160014fe3e9ef1a745e974d902c4355943abcb34bd5353ffffffff0200c2eb0b000000001976a91485cff1097fd9e008bb34af709c62197b38978a4888ac72fef84e2c00000017a914339725ba21efd62ac753a9bcd067d6c7a6a39d05870247304402202712be22e0270f394f568311dc7ca9a68970b8025fdd3b240229f07f8a5f3a240220018b38d7dcd314e734c9276bd6fb40f673325bc4baa144c800d2f2f02db2765c012103d2e15674941bad4a996372cb87e1856d3652606d98562fe39c5e9e7e413f210502483045022100d12b852d85dcd961d2f5f4ab660654df6eedcc794c0c33ce5cc309ffb5fce58d022067338a8e0e1725c197fb1a88af59f51e44e4255b20167c8684031c05d1f2592a01210223b72beef0965d10be0778efecd61fcac6f79a4ea169393380734464f84f2ab30000000000")
// This weird thing is necessary since rustc 0.29 prints out I/O error in a different format than later versions
.map_err(Error::from)
.unwrap();
}
Expand All @@ -477,7 +500,14 @@ mod tests {
#[test]
#[should_panic(expected = "ConsensusEncoding")]
fn invalid_vector_2_base64() {
PartiallySignedTransaction::from_str("cHNidP8BAHUCAAAAASaBcTce3/KF6Tet7qSze3gADAVmy7OtZGQXE8pCFxv2AAAAAAD+////AtPf9QUAAAAAGXapFNDFmQPFusKGh2DpD9UhpGZap2UgiKwA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHh7MuEwAAAQD9pQEBAAAAAAECiaPHHqtNIOA3G7ukzGmPopXJRjr6Ljl/hTPMti+VZ+UBAAAAFxYAFL4Y0VKpsBIDna89p95PUzSe7LmF/////4b4qkOnHf8USIk6UwpyN+9rRgi7st0tAXHmOuxqSJC0AQAAABcWABT+Pp7xp0XpdNkCxDVZQ6vLNL1TU/////8CAMLrCwAAAAAZdqkUhc/xCX/Z4Ai7NK9wnGIZeziXikiIrHL++E4sAAAAF6kUM5cluiHv1irHU6m80GfWx6ajnQWHAkcwRAIgJxK+IuAnDzlPVoMR3HyppolwuAJf3TskAinwf4pfOiQCIAGLONfc0xTnNMkna9b7QPZzMlvEuqFEyADS8vAtsnZcASED0uFWdJQbrUqZY3LLh+GFbTZSYG2YVi/jnF6efkE/IQUCSDBFAiEA0SuFLYXc2WHS9fSrZgZU327tzHlMDDPOXMMJ/7X85Y0CIGczio4OFyXBl/saiK9Z9R5E5CVbIBZ8hoQDHAXR8lkqASECI7cr7vCWXRC+B3jv7NYfysb3mk6haTkzgHNEZPhPKrMAAAAAAA==").unwrap();
PartiallySignedTransaction::from_str("cHNidP8BAHUCAAAAASaBcTce3/KF6Tet7qSze3gADAVmy7OtZGQXE8pCFxv2AAAAAAD+////AtPf9QUAAAAAGXapFNDFmQPFusKGh2DpD9UhpGZap2UgiKwA4fUFAAAAABepFDVF5uM7gyxHBQ8k0+65PJwDlIvHh7MuEwAAAQD9pQEBAAAAAAECiaPHHqtNIOA3G7ukzGmPopXJRjr6Ljl/hTPMti+VZ+UBAAAAFxYAFL4Y0VKpsBIDna89p95PUzSe7LmF/////4b4qkOnHf8USIk6UwpyN+9rRgi7st0tAXHmOuxqSJC0AQAAABcWABT+Pp7xp0XpdNkCxDVZQ6vLNL1TU/////8CAMLrCwAAAAAZdqkUhc/xCX/Z4Ai7NK9wnGIZeziXikiIrHL++E4sAAAAF6kUM5cluiHv1irHU6m80GfWx6ajnQWHAkcwRAIgJxK+IuAnDzlPVoMR3HyppolwuAJf3TskAinwf4pfOiQCIAGLONfc0xTnNMkna9b7QPZzMlvEuqFEyADS8vAtsnZcASED0uFWdJQbrUqZY3LLh+GFbTZSYG2YVi/jnF6efkE/IQUCSDBFAiEA0SuFLYXc2WHS9fSrZgZU327tzHlMDDPOXMMJ/7X85Y0CIGczio4OFyXBl/saiK9Z9R5E5CVbIBZ8hoQDHAXR8lkqASECI7cr7vCWXRC+B3jv7NYfysb3mk6haTkzgHNEZPhPKrMAAAAAAA==")
// This weird thing is necessary since rustc 0.29 prints out I/O error in a different format than later versions
.map_err(|err| match err {
PsbtParseError::PsbtEncoding(err) => err,
PsbtParseError::Base64Encoding(_) => panic!("PSBT Base64 decoding failed")
})
.map_err(Error::from)
.unwrap();
}

#[test]
Expand Down

0 comments on commit f92f164

Please sign in to comment.