From e7bbfd391353fd03d60550c768364e9de5d3e8c5 Mon Sep 17 00:00:00 2001 From: DanGould Date: Fri, 9 Dec 2022 11:55:11 -0500 Subject: [PATCH] Improve Psbt error handling Remove recursive dependence between encode::Error and psbt::Error. Separate consensus encoding errors from Psbt application errors. --- bitcoin/src/consensus/encode.rs | 12 ------ bitcoin/src/consensus/serde.rs | 1 - bitcoin/src/psbt/error.rs | 11 ++--- bitcoin/src/psbt/macros.rs | 14 +++--- bitcoin/src/psbt/map/global.rs | 34 +++++++-------- bitcoin/src/psbt/map/input.rs | 16 +++---- bitcoin/src/psbt/map/output.rs | 7 ++- bitcoin/src/psbt/mod.rs | 7 ++- bitcoin/src/psbt/raw.rs | 10 ++--- bitcoin/src/psbt/serialize.rs | 76 ++++++++++++++++----------------- 10 files changed, 86 insertions(+), 102 deletions(-) diff --git a/bitcoin/src/consensus/encode.rs b/bitcoin/src/consensus/encode.rs index 2b777fe6..11086f40 100644 --- a/bitcoin/src/consensus/encode.rs +++ b/bitcoin/src/consensus/encode.rs @@ -26,7 +26,6 @@ use crate::hashes::{sha256d, Hash, sha256}; use crate::hash_types::{BlockHash, FilterHash, TxMerkleNode, FilterHeader}; use crate::io::{self, Cursor, Read}; -use crate::psbt; use crate::bip152::{ShortId, PrefilledTransaction}; use crate::taproot::TapLeafHash; @@ -40,8 +39,6 @@ use crate::network::{message_blockdata::Inventory, address::{Address, AddrV2Mess pub enum Error { /// And I/O error. Io(io::Error), - /// PSBT-related error. - Psbt(psbt::Error), /// Tried to allocate an oversized vector. OversizedVectorAllocation { /// The capacity requested. @@ -68,7 +65,6 @@ impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { Error::Io(ref e) => write_err!(f, "IO error"; e), - Error::Psbt(ref e) => write_err!(f, "PSBT error"; e), Error::OversizedVectorAllocation { requested: ref r, max: ref m } => write!(f, "allocation of oversized vector: requested {}, maximum {}", r, m), Error::InvalidChecksum { expected: ref e, actual: ref a } => write!(f, @@ -89,7 +85,6 @@ impl std::error::Error for Error { match self { Io(e) => Some(e), - Psbt(e) => Some(e), OversizedVectorAllocation { .. } | InvalidChecksum { .. } | NonMinimalVarInt @@ -106,13 +101,6 @@ impl From for Error { } } -#[doc(hidden)] -impl From for Error { - fn from(e: psbt::Error) -> Error { - Error::Psbt(e) - } -} - /// Encodes an object into a vector. pub fn serialize(data: &T) -> Vec { let mut encoder = Vec::new(); diff --git a/bitcoin/src/consensus/serde.rs b/bitcoin/src/consensus/serde.rs index 6de7ddfa..cbae90cd 100644 --- a/bitcoin/src/consensus/serde.rs +++ b/bitcoin/src/consensus/serde.rs @@ -372,7 +372,6 @@ enum DecodeError { fn consensus_error_into_serde(error: ConsensusError) -> E { match error { ConsensusError::Io(error) => panic!("unexpected IO error {:?}", error), - ConsensusError::Psbt(_) => panic!("PSBT shouldn't implement consensus encoding"), ConsensusError::OversizedVectorAllocation { requested, max } => E::custom(format_args!("the requested allocation of {} items exceeds maximum of {}", requested, max)), ConsensusError::InvalidChecksum { expected, actual } => E::invalid_value(Unexpected::Bytes(&actual), &DisplayExpected(format_args!("checksum {:02x}{:02x}{:02x}{:02x}", expected[0], expected[1], expected[2], expected[3]))), ConsensusError::NonMinimalVarInt => E::custom(format_args!("compact size was not encoded minimally")), diff --git a/bitcoin/src/psbt/error.rs b/bitcoin/src/psbt/error.rs index e9079e8e..29b3d7cc 100644 --- a/bitcoin/src/psbt/error.rs +++ b/bitcoin/src/psbt/error.rs @@ -72,6 +72,8 @@ pub enum Error { /// Conflicting data during combine procedure: /// global extended public key has inconsistent key sources CombineInconsistentKeySources(Box), + /// Parsing error. + ParseFailed(&'static str), /// Serialization error in bitcoin consensus-encoded structures ConsensusEncoding, /// Negative fee @@ -104,6 +106,7 @@ impl fmt::Display for Error { write!(f, "Preimage {:?} does not match {:?} hash {:?}", preimage, hash_type, hash ) }, Error::CombineInconsistentKeySources(ref s) => { write!(f, "combine conflict: {}", s) }, + Error::ParseFailed(ref s) => write!(f, "parse failed: {}", s), Error::ConsensusEncoding => f.write_str("bitcoin consensus or BIP-174 encoding error"), Error::NegativeFee => f.write_str("PSBT has a negative fee which is not allowed"), Error::FeeOverflow => f.write_str("integer overflow in fee calculation"), @@ -135,6 +138,7 @@ impl std::error::Error for Error { | NonStandardSighashType(_) | InvalidPreimageHashPair{ .. } | CombineInconsistentKeySources(_) + | ParseFailed(_) | ConsensusEncoding | NegativeFee | FeeOverflow => None, @@ -150,10 +154,7 @@ impl From for Error { } impl From for Error { - fn from(err: encode::Error) -> Self { - match err { - encode::Error::Psbt(err) => err, - _ => Error::ConsensusEncoding, - } + fn from(_: encode::Error) -> Self { + Error::ConsensusEncoding } } diff --git a/bitcoin/src/psbt/macros.rs b/bitcoin/src/psbt/macros.rs index a5aedd3d..cdb4e86b 100644 --- a/bitcoin/src/psbt/macros.rs +++ b/bitcoin/src/psbt/macros.rs @@ -23,8 +23,8 @@ macro_rules! impl_psbt_de_serialize { macro_rules! impl_psbt_deserialize { ($thing:ty) => { impl $crate::psbt::serialize::Deserialize for $thing { - fn deserialize(bytes: &[u8]) -> Result { - $crate::consensus::deserialize(&bytes[..]) + fn deserialize(bytes: &[u8]) -> Result { + $crate::consensus::deserialize(&bytes[..]).map_err(|e| $crate::psbt::Error::from(e)) } } }; @@ -53,7 +53,7 @@ macro_rules! impl_psbtmap_serialize { macro_rules! impl_psbtmap_deserialize { ($thing:ty) => { impl $crate::psbt::serialize::Deserialize for $thing { - fn deserialize(bytes: &[u8]) -> Result { + fn deserialize(bytes: &[u8]) -> Result { let mut decoder = bytes; Self::decode(&mut decoder) } @@ -66,13 +66,13 @@ macro_rules! impl_psbtmap_decoding { impl $thing { pub(crate) fn decode( r: &mut R, - ) -> Result { + ) -> Result { let mut rv: Self = core::default::Default::default(); loop { match $crate::psbt::raw::Pair::decode(r) { Ok(pair) => rv.insert_pair(pair)?, - Err($crate::consensus::encode::Error::Psbt($crate::psbt::Error::NoMorePairs)) => return Ok(rv), + Err($crate::psbt::Error::NoMorePairs) => return Ok(rv), Err(e) => return Err(e), } } @@ -156,9 +156,9 @@ macro_rules! impl_psbt_hash_de_serialize { macro_rules! impl_psbt_hash_deserialize { ($hash_type:ty) => { impl $crate::psbt::serialize::Deserialize for $hash_type { - fn deserialize(bytes: &[u8]) -> Result { + fn deserialize(bytes: &[u8]) -> Result { <$hash_type>::from_slice(&bytes[..]).map_err(|e| { - $crate::psbt::Error::from(e).into() + $crate::psbt::Error::from(e) }) } } diff --git a/bitcoin/src/psbt/map/global.rs b/bitcoin/src/psbt/map/global.rs index 6074bd65..e443e6c9 100644 --- a/bitcoin/src/psbt/map/global.rs +++ b/bitcoin/src/psbt/map/global.rs @@ -88,7 +88,7 @@ impl Map for PartiallySignedTransaction { } impl PartiallySignedTransaction { - pub(crate) fn decode_global(r: &mut R) -> Result { + pub(crate) fn decode_global(r: &mut R) -> Result { let mut r = r.take(MAX_VEC_SIZE as u64); let mut tx: Option = None; let mut version: Option = None; @@ -119,30 +119,30 @@ impl PartiallySignedTransaction { }); if decoder.position() != vlen as u64 { - return Err(encode::Error::ParseFailed("data not consumed entirely when explicitly deserializing")) + return Err(Error::ParseFailed("data not consumed entirely when explicitly deserializing")) } } else { - return Err(Error::DuplicateKey(pair.key).into()) + return Err(Error::DuplicateKey(pair.key)) } } else { - return Err(Error::InvalidKey(pair.key).into()) + return Err(Error::InvalidKey(pair.key)) } } PSBT_GLOBAL_XPUB => { if !pair.key.key.is_empty() { let xpub = ExtendedPubKey::decode(&pair.key.key) - .map_err(|_| encode::Error::ParseFailed( + .map_err(|_| Error::ParseFailed( "Can't deserialize ExtendedPublicKey from global XPUB key data" ))?; if pair.value.is_empty() || pair.value.len() % 4 != 0 { - return Err(encode::Error::ParseFailed("Incorrect length of global xpub derivation data")) + return Err(Error::ParseFailed("Incorrect length of global xpub derivation data")) } let child_count = pair.value.len() / 4 - 1; let mut decoder = Cursor::new(pair.value); let mut fingerprint = [0u8; 4]; - decoder.read_exact(&mut fingerprint[..])?; + decoder.read_exact(&mut fingerprint[..]).map_err(|_| Error::ParseFailed("Can't read global xpub fingerprint"))?; let mut path = Vec::::with_capacity(child_count); while let Ok(index) = u32::consensus_decode(&mut decoder) { path.push(ChildNumber::from(index)) @@ -150,10 +150,10 @@ impl PartiallySignedTransaction { let derivation = DerivationPath::from(path); // Keys, according to BIP-174, must be unique if xpub_map.insert(xpub, (Fingerprint::from(fingerprint), derivation)).is_some() { - return Err(encode::Error::ParseFailed("Repeated global xpub key")) + return Err(Error::ParseFailed("Repeated global xpub key")) } } else { - return Err(encode::Error::ParseFailed("Xpub global key must contain serialized Xpub data")) + return Err(Error::ParseFailed("Xpub global key must contain serialized Xpub data")) } } PSBT_GLOBAL_VERSION => { @@ -164,36 +164,36 @@ impl PartiallySignedTransaction { let vlen: usize = pair.value.len(); let mut decoder = Cursor::new(pair.value); if vlen != 4 { - return Err(encode::Error::ParseFailed("Wrong global version value length (must be 4 bytes)")) + return Err(Error::ParseFailed("Wrong global version value length (must be 4 bytes)")) } version = Some(Decodable::consensus_decode(&mut decoder)?); // We only understand version 0 PSBTs. According to BIP-174 we // should throw an error if we see anything other than version 0. if version != Some(0) { - return Err(encode::Error::ParseFailed("PSBT versions greater than 0 are not supported")) + return Err(Error::ParseFailed("PSBT versions greater than 0 are not supported")) } } else { - return Err(Error::DuplicateKey(pair.key).into()) + return Err(Error::DuplicateKey(pair.key)) } } else { - return Err(Error::InvalidKey(pair.key).into()) + return Err(Error::InvalidKey(pair.key)) } } PSBT_GLOBAL_PROPRIETARY => match proprietary.entry(raw::ProprietaryKey::try_from(pair.key.clone())?) { btree_map::Entry::Vacant(empty_key) => { empty_key.insert(pair.value); }, - btree_map::Entry::Occupied(_) => return Err(Error::DuplicateKey(pair.key).into()), + btree_map::Entry::Occupied(_) => return Err(Error::DuplicateKey(pair.key)), } _ => match unknowns.entry(pair.key) { btree_map::Entry::Vacant(empty_key) => { empty_key.insert(pair.value); }, - btree_map::Entry::Occupied(k) => return Err(Error::DuplicateKey(k.key().clone()).into()), + btree_map::Entry::Occupied(k) => return Err(Error::DuplicateKey(k.key().clone())), } } } - Err(crate::consensus::encode::Error::Psbt(crate::psbt::Error::NoMorePairs)) => break, + Err(crate::psbt::Error::NoMorePairs) => break, Err(e) => return Err(e), } } @@ -209,7 +209,7 @@ impl PartiallySignedTransaction { outputs: vec![] }) } else { - Err(Error::MustHaveUnsignedTx.into()) + Err(Error::MustHaveUnsignedTx) } } } diff --git a/bitcoin/src/psbt/map/input.rs b/bitcoin/src/psbt/map/input.rs index 0e69fcea..8ae6e987 100644 --- a/bitcoin/src/psbt/map/input.rs +++ b/bitcoin/src/psbt/map/input.rs @@ -11,7 +11,6 @@ use secp256k1::XOnlyPublicKey; use crate::blockdata::script::ScriptBuf; use crate::blockdata::witness::Witness; use crate::blockdata::transaction::{Transaction, TxOut}; -use crate::consensus::encode; use crate::crypto::{ecdsa, schnorr}; use crate::crypto::key::PublicKey; use crate::hashes::{self, hash160, ripemd160, sha256, sha256d}; @@ -247,7 +246,7 @@ impl Input { .unwrap_or(Ok(SchnorrSighashType::Default)) } - pub(super) fn insert_pair(&mut self, pair: raw::Pair) -> Result<(), encode::Error> { + pub(super) fn insert_pair(&mut self, pair: raw::Pair) -> Result<(), Error> { let raw::Pair { key: raw_key, value: raw_value, @@ -347,14 +346,14 @@ impl Input { btree_map::Entry::Vacant(empty_key) => { empty_key.insert(raw_value); }, - btree_map::Entry::Occupied(_) => return Err(Error::DuplicateKey(raw_key).into()), + btree_map::Entry::Occupied(_) => return Err(Error::DuplicateKey(raw_key)), } } _ => match self.unknown.entry(raw_key) { btree_map::Entry::Vacant(empty_key) => { empty_key.insert(raw_value); } - btree_map::Entry::Occupied(k) => return Err(Error::DuplicateKey(k.key().clone()).into()), + btree_map::Entry::Occupied(k) => return Err(Error::DuplicateKey(k.key().clone())), }, } @@ -496,12 +495,12 @@ fn psbt_insert_hash_pair( raw_key: raw::Key, raw_value: Vec, hash_type: error::PsbtHash, -) -> Result<(), encode::Error> +) -> Result<(), Error> where H: hashes::Hash + Deserialize, { if raw_key.key.is_empty() { - return Err(psbt::Error::InvalidKey(raw_key).into()); + return Err(psbt::Error::InvalidKey(raw_key)); } let key_val: H = Deserialize::deserialize(&raw_key.key)?; match map.entry(key_val) { @@ -512,13 +511,12 @@ where preimage: val.into_boxed_slice(), hash: Box::from(key_val.borrow()), hash_type, - } - .into()); + }); } empty_key.insert(val); Ok(()) } - btree_map::Entry::Occupied(_) => Err(psbt::Error::DuplicateKey(raw_key).into()), + btree_map::Entry::Occupied(_) => Err(psbt::Error::DuplicateKey(raw_key)), } } diff --git a/bitcoin/src/psbt/map/output.rs b/bitcoin/src/psbt/map/output.rs index d360ac4d..6389da0d 100644 --- a/bitcoin/src/psbt/map/output.rs +++ b/bitcoin/src/psbt/map/output.rs @@ -5,7 +5,6 @@ use core; use core::convert::TryFrom; use crate::blockdata::script::ScriptBuf; -use crate::consensus::encode; use secp256k1::XOnlyPublicKey; use crate::bip32::KeySource; use secp256k1; @@ -205,7 +204,7 @@ impl<'tree> Iterator for TapTreeIter<'tree> { } impl Output { - pub(super) fn insert_pair(&mut self, pair: raw::Pair) -> Result<(), encode::Error> { + pub(super) fn insert_pair(&mut self, pair: raw::Pair) -> Result<(), Error> { let raw::Pair { key: raw_key, value: raw_value, @@ -233,7 +232,7 @@ impl Output { btree_map::Entry::Vacant(empty_key) => { empty_key.insert(raw_value); }, - btree_map::Entry::Occupied(_) => return Err(Error::DuplicateKey(raw_key).into()), + btree_map::Entry::Occupied(_) => return Err(Error::DuplicateKey(raw_key)), } } PSBT_OUT_TAP_INTERNAL_KEY => { @@ -255,7 +254,7 @@ impl Output { btree_map::Entry::Vacant(empty_key) => { empty_key.insert(raw_value); } - btree_map::Entry::Occupied(k) => return Err(Error::DuplicateKey(k.key().clone()).into()), + btree_map::Entry::Occupied(k) => return Err(Error::DuplicateKey(k.key().clone())), } } diff --git a/bitcoin/src/psbt/mod.rs b/bitcoin/src/psbt/mod.rs index 42ba1e53..9a09ba67 100644 --- a/bitcoin/src/psbt/mod.rs +++ b/bitcoin/src/psbt/mod.rs @@ -745,10 +745,9 @@ impl From for SignError { #[cfg(feature = "base64")] mod display_from_str { - use super::PartiallySignedTransaction; + use super::{PartiallySignedTransaction, Error}; use core::fmt::{Display, Formatter, self}; use core::str::FromStr; - use crate::consensus::encode::Error; use base64::display::Base64Display; use bitcoin_internals::write_err; @@ -1396,9 +1395,9 @@ mod tests { assert_eq!(err.to_string(), "parse failed: Invalid xonly public key"); let err = hex_psbt!("70736274ff01005e02000000019bd48765230bf9a72e662001f972556e54f0c6f97feb56bcb5600d817f6995260100000000ffffffff0148e6052a01000000225120030da4fce4f7db28c2cb2951631e003713856597fe963882cb500e68112cca63000000000001012b00f2052a01000000225120c2247efbfd92ac47f6f40b8d42d169175a19fa9fa10e4a25d7f35eb4dd85b6924214022cb13ac68248de806aa6a3659cf3c03eb6821d09c8114a4e868febde865bb6d2cd970e15f53fc0c82f950fd560ffa919b76172be017368a89913af074f400b094089756aa3739ccc689ec0fcf3a360be32cc0b59b16e93a1e8bb4605726b2ca7a3ff706c4176649632b2cc68e1f912b8a578e3719ce7710885c7a966f49bcd43cb0000").unwrap_err(); #[cfg(feature = "std")] - assert_eq!(err.to_string(), "PSBT error"); + assert_eq!(err.to_string(), "hash parse error"); #[cfg(not(feature = "std"))] - assert_eq!(err.to_string(), "PSBT error: hash parse error: bad slice length 33 (expected 32)"); + assert_eq!(err.to_string(), "hash parse error: bad slice length 33 (expected 32)"); let err = hex_psbt!("70736274ff01005e02000000019bd48765230bf9a72e662001f972556e54f0c6f97feb56bcb5600d817f6995260100000000ffffffff0148e6052a01000000225120030da4fce4f7db28c2cb2951631e003713856597fe963882cb500e68112cca63000000000001012b00f2052a01000000225120c2247efbfd92ac47f6f40b8d42d169175a19fa9fa10e4a25d7f35eb4dd85b69241142cb13ac68248de806aa6a3659cf3c03eb6821d09c8114a4e868febde865bb6d2cd970e15f53fc0c82f950fd560ffa919b76172be017368a89913af074f400b094289756aa3739ccc689ec0fcf3a360be32cc0b59b16e93a1e8bb4605726b2ca7a3ff706c4176649632b2cc68e1f912b8a578e3719ce7710885c7a966f49bcd43cb01010000").unwrap_err(); assert_eq!(err.to_string(), "parse failed: Invalid Schnorr signature length"); let err = hex_psbt!("70736274ff01005e02000000019bd48765230bf9a72e662001f972556e54f0c6f97feb56bcb5600d817f6995260100000000ffffffff0148e6052a01000000225120030da4fce4f7db28c2cb2951631e003713856597fe963882cb500e68112cca63000000000001012b00f2052a01000000225120c2247efbfd92ac47f6f40b8d42d169175a19fa9fa10e4a25d7f35eb4dd85b69241142cb13ac68248de806aa6a3659cf3c03eb6821d09c8114a4e868febde865bb6d2cd970e15f53fc0c82f950fd560ffa919b76172be017368a89913af074f400b093989756aa3739ccc689ec0fcf3a360be32cc0b59b16e93a1e8bb4605726b2ca7a3ff706c4176649632b2cc68e1f912b8a578e3719ce7710885c7a966f49bcd43cb0000").unwrap_err(); diff --git a/bitcoin/src/psbt/raw.rs b/bitcoin/src/psbt/raw.rs index 40fdf889..94ab4eab 100644 --- a/bitcoin/src/psbt/raw.rs +++ b/bitcoin/src/psbt/raw.rs @@ -70,11 +70,11 @@ impl fmt::Display for Key { } impl Key { - pub(crate) fn decode(r: &mut R) -> Result { + pub(crate) fn decode(r: &mut R) -> Result { let VarInt(byte_size): VarInt = Decodable::consensus_decode(r)?; if byte_size == 0 { - return Err(Error::NoMorePairs.into()); + return Err(Error::NoMorePairs); } let key_byte_size: u64 = byte_size - 1; @@ -83,7 +83,7 @@ impl Key { return Err(encode::Error::OversizedVectorAllocation { requested: key_byte_size as usize, max: MAX_VEC_SIZE, - }) + })? } let type_value: u8 = Decodable::consensus_decode(r)?; @@ -123,14 +123,14 @@ impl Serialize for Pair { } impl Deserialize for Pair { - fn deserialize(bytes: &[u8]) -> Result { + fn deserialize(bytes: &[u8]) -> Result { let mut decoder = bytes; Pair::decode(&mut decoder) } } impl Pair { - pub(crate) fn decode(r: &mut R) -> Result { + pub(crate) fn decode(r: &mut R) -> Result { Ok(Pair { key: Key::decode(r)?, value: Decodable::consensus_decode(r)?, diff --git a/bitcoin/src/psbt/serialize.rs b/bitcoin/src/psbt/serialize.rs index 5a9e9ec1..93c6ac7c 100644 --- a/bitcoin/src/psbt/serialize.rs +++ b/bitcoin/src/psbt/serialize.rs @@ -20,7 +20,7 @@ use secp256k1::{self, XOnlyPublicKey}; use crate::bip32::{ChildNumber, Fingerprint, KeySource}; use crate::hashes::{hash160, ripemd160, sha256, sha256d, Hash}; use crate::crypto::{ecdsa, schnorr}; -use crate::psbt::{self, Error, PartiallySignedTransaction}; +use crate::psbt::{Error, PartiallySignedTransaction}; use crate::taproot::{TapNodeHash, TapLeafHash, ControlBlock, LeafVersion}; use crate::crypto::key::PublicKey; @@ -38,7 +38,7 @@ pub(crate) trait Serialize { /// A trait for deserializing a value from raw data in PSBT key-value maps. pub(crate) trait Deserialize: Sized { /// Deserialize a value from raw data. - fn deserialize(bytes: &[u8]) -> Result; + fn deserialize(bytes: &[u8]) -> Result; } impl PartiallySignedTransaction { @@ -71,15 +71,15 @@ impl PartiallySignedTransaction { /// Deserialize a value from raw binary data. - pub fn deserialize(bytes: &[u8]) -> Result { + pub fn deserialize(bytes: &[u8]) -> Result { const MAGIC_BYTES: &[u8] = b"psbt"; if bytes.get(0..MAGIC_BYTES.len()) != Some(MAGIC_BYTES) { - return Err(Error::InvalidMagic.into()); + return Err(Error::InvalidMagic); } const PSBT_SERPARATOR: u8 = 0xff_u8; if bytes.get(MAGIC_BYTES.len()) != Some(&PSBT_SERPARATOR) { - return Err(Error::InvalidSeparator.into()); + return Err(Error::InvalidSeparator); } let mut d = bytes.get(5..).ok_or(Error::NoMorePairs)?; @@ -136,7 +136,7 @@ impl Serialize for ScriptBuf { } impl Deserialize for ScriptBuf { - fn deserialize(bytes: &[u8]) -> Result { + fn deserialize(bytes: &[u8]) -> Result { Ok(Self::from(bytes.to_vec())) } } @@ -150,9 +150,9 @@ impl Serialize for PublicKey { } impl Deserialize for PublicKey { - fn deserialize(bytes: &[u8]) -> Result { + fn deserialize(bytes: &[u8]) -> Result { PublicKey::from_slice(bytes) - .map_err(|_| encode::Error::ParseFailed("invalid public key")) + .map_err(|_| Error::ParseFailed("invalid public key")) } } @@ -163,9 +163,9 @@ impl Serialize for secp256k1::PublicKey { } impl Deserialize for secp256k1::PublicKey { - fn deserialize(bytes: &[u8]) -> Result { + fn deserialize(bytes: &[u8]) -> Result { secp256k1::PublicKey::from_slice(bytes) - .map_err(|_| encode::Error::ParseFailed("invalid public key")) + .map_err(|_| Error::ParseFailed("invalid public key")) } } @@ -176,7 +176,7 @@ impl Serialize for ecdsa::Signature { } impl Deserialize for ecdsa::Signature { - fn deserialize(bytes: &[u8]) -> Result { + fn deserialize(bytes: &[u8]) -> Result { // NB: Since BIP-174 says "the signature as would be pushed to the stack from // a scriptSig or witness" we should ideally use a consensus deserialization and do // not error on a non-standard values. However, @@ -193,13 +193,13 @@ impl Deserialize for ecdsa::Signature { ecdsa::Signature::from_slice(bytes) .map_err(|e| match e { ecdsa::Error::EmptySignature => { - encode::Error::ParseFailed("Empty partial signature data") + Error::ParseFailed("Empty partial signature data") } ecdsa::Error::NonStandardSighashType(flag) => { - encode::Error::from(psbt::Error::NonStandardSighashType(flag)) + Error::NonStandardSighashType(flag) } ecdsa::Error::Secp256k1(..) => { - encode::Error::ParseFailed("Invalid Ecdsa signature") + Error::ParseFailed("Invalid Ecdsa signature") } ecdsa::Error::HexEncoding(..) => { unreachable!("Decoding from slice, not hex") @@ -223,9 +223,9 @@ impl Serialize for KeySource { } impl Deserialize for KeySource { - fn deserialize(bytes: &[u8]) -> Result { + fn deserialize(bytes: &[u8]) -> Result { if bytes.len() < 4 { - return Err(io::Error::from(io::ErrorKind::UnexpectedEof).into()) + return Err(encode::Error::from(io::Error::from(io::ErrorKind::UnexpectedEof)).into()) } let fprint: Fingerprint = bytes[0..4].try_into().expect("4 is the fingerprint length"); @@ -235,7 +235,7 @@ impl Deserialize for KeySource { while !d.is_empty() { match u32::consensus_decode(&mut d) { Ok(index) => dpath.push(index.into()), - Err(e) => return Err(e), + Err(e) => return Err(e)?, } } @@ -251,7 +251,7 @@ impl Serialize for Vec { } impl Deserialize for Vec { - fn deserialize(bytes: &[u8]) -> Result { + fn deserialize(bytes: &[u8]) -> Result { Ok(bytes.to_vec()) } } @@ -263,7 +263,7 @@ impl Serialize for PsbtSighashType { } impl Deserialize for PsbtSighashType { - fn deserialize(bytes: &[u8]) -> Result { + fn deserialize(bytes: &[u8]) -> Result { let raw: u32 = encode::deserialize(bytes)?; Ok(PsbtSighashType { inner: raw }) } @@ -277,9 +277,9 @@ impl Serialize for XOnlyPublicKey { } impl Deserialize for XOnlyPublicKey { - fn deserialize(bytes: &[u8]) -> Result { + fn deserialize(bytes: &[u8]) -> Result { XOnlyPublicKey::from_slice(bytes) - .map_err(|_| encode::Error::ParseFailed("Invalid xonly public key")) + .map_err(|_| Error::ParseFailed("Invalid xonly public key")) } } @@ -290,17 +290,17 @@ impl Serialize for schnorr::Signature { } impl Deserialize for schnorr::Signature { - fn deserialize(bytes: &[u8]) -> Result { + fn deserialize(bytes: &[u8]) -> Result { schnorr::Signature::from_slice(bytes) .map_err(|e| match e { schnorr::Error::InvalidSighashType(flag) => { - encode::Error::from(psbt::Error::NonStandardSighashType(flag as u32)) + Error::NonStandardSighashType(flag as u32) } schnorr::Error::InvalidSignatureSize(_) => { - encode::Error::ParseFailed("Invalid Schnorr signature length") + Error::ParseFailed("Invalid Schnorr signature length") } schnorr::Error::Secp256k1(..) => { - encode::Error::ParseFailed("Invalid Schnorr signature") + Error::ParseFailed("Invalid Schnorr signature") } }) } @@ -317,9 +317,9 @@ impl Serialize for (XOnlyPublicKey, TapLeafHash) { } impl Deserialize for (XOnlyPublicKey, TapLeafHash) { - fn deserialize(bytes: &[u8]) -> Result { + fn deserialize(bytes: &[u8]) -> Result { if bytes.len() < 32 { - return Err(io::Error::from(io::ErrorKind::UnexpectedEof).into()) + return Err(encode::Error::from(io::Error::from(io::ErrorKind::UnexpectedEof)).into()) } let a: XOnlyPublicKey = Deserialize::deserialize(&bytes[..32])?; let b: TapLeafHash = Deserialize::deserialize(&bytes[32..])?; @@ -334,9 +334,9 @@ impl Serialize for ControlBlock { } impl Deserialize for ControlBlock { - fn deserialize(bytes: &[u8]) -> Result { + fn deserialize(bytes: &[u8]) -> Result { Self::from_slice(bytes) - .map_err(|_| encode::Error::ParseFailed("Invalid control block")) + .map_err(|_| Error::ParseFailed("Invalid control block")) } } @@ -351,14 +351,14 @@ impl Serialize for (ScriptBuf, LeafVersion) { } impl Deserialize for (ScriptBuf, LeafVersion) { - fn deserialize(bytes: &[u8]) -> Result { + fn deserialize(bytes: &[u8]) -> Result { if bytes.is_empty() { - return Err(io::Error::from(io::ErrorKind::UnexpectedEof).into()) + return Err(encode::Error::from(io::Error::from(io::ErrorKind::UnexpectedEof)).into()) } // The last byte is LeafVersion. let script = ScriptBuf::deserialize(&bytes[..bytes.len() - 1])?; let leaf_ver = LeafVersion::from_consensus(bytes[bytes.len() - 1]) - .map_err(|_| encode::Error::ParseFailed("invalid leaf version"))?; + .map_err(|_| Error::ParseFailed("invalid leaf version"))?; Ok((script, leaf_ver)) } } @@ -375,7 +375,7 @@ impl Serialize for (Vec, KeySource) { } impl Deserialize for (Vec, KeySource) { - fn deserialize(bytes: &[u8]) -> Result { + fn deserialize(bytes: &[u8]) -> Result { let (leafhash_vec, consumed) = deserialize_partial::>(bytes)?; let key_source = KeySource::deserialize(&bytes[consumed..])?; Ok((leafhash_vec, key_source)) @@ -405,25 +405,25 @@ impl Serialize for TapTree { } impl Deserialize for TapTree { - fn deserialize(bytes: &[u8]) -> Result { + fn deserialize(bytes: &[u8]) -> Result { let mut builder = TaprootBuilder::new(); let mut bytes_iter = bytes.iter(); while let Some(depth) = bytes_iter.next() { - let version = bytes_iter.next().ok_or(encode::Error::ParseFailed("Invalid Taproot Builder"))?; + let version = bytes_iter.next().ok_or(Error::ParseFailed("Invalid Taproot Builder"))?; let (script, consumed) = deserialize_partial::(bytes_iter.as_slice())?; if consumed > 0 { bytes_iter.nth(consumed - 1); } let leaf_version = LeafVersion::from_consensus(*version) - .map_err(|_| encode::Error::ParseFailed("Leaf Version Error"))?; + .map_err(|_| Error::ParseFailed("Leaf Version Error"))?; builder = builder.add_leaf_with_ver(*depth, script, leaf_version) - .map_err(|_| encode::Error::ParseFailed("Tree not in DFS order"))?; + .map_err(|_| Error::ParseFailed("Tree not in DFS order"))?; } if builder.is_finalizable() && !builder.has_hidden_nodes() { Ok(TapTree(builder)) } else { - Err(encode::Error::ParseFailed("Incomplete taproot Tree")) + Err(Error::ParseFailed("Incomplete taproot Tree")) } } }