diff --git a/bitcoin/src/consensus/encode.rs b/bitcoin/src/consensus/encode.rs index 462e68a31..3af089b30 100644 --- a/bitcoin/src/consensus/encode.rs +++ b/bitcoin/src/consensus/encode.rs @@ -1164,7 +1164,7 @@ mod tests { hex.push_str("abcdef"); assert!(matches!( deserialize_hex::(&hex).unwrap_err(), - FromHexError::Decode(DecodeError::TooManyBytes) + FromHexError::Decode(DecodeError::Unconsumed) )); } } diff --git a/bitcoin/src/consensus/error.rs b/bitcoin/src/consensus/error.rs index 4321cf776..cfd9f256a 100644 --- a/bitcoin/src/consensus/error.rs +++ b/bitcoin/src/consensus/error.rs @@ -51,14 +51,17 @@ impl From for DeserializeError { } /// Error when consensus decoding from an `[IterReader]`. +/// +/// This is the same as a `DeserializeError` with an additional variant to return any error yealded +/// by the inner bytes iterator. #[derive(Debug)] pub enum DecodeError { - /// Attempted to decode an object from an iterator that yielded too many bytes. - TooManyBytes, /// Invalid consensus encoding. - Consensus(Error), + Parse(ParseError), + /// Data unconsumed error. + Unconsumed, /// Other decoding error. - Other(E), + Other(E), // Yielded by the inner iterator. } internals::impl_from_infallible!(DecodeError); @@ -68,9 +71,8 @@ impl fmt::Display for DecodeError { use DecodeError::*; match *self { - TooManyBytes => - write!(f, "attempted to decode object from an iterator that yielded too many bytes"), - Consensus(ref e) => write_err!(f, "invalid consensus encoding"; e), + Parse(ref e) => write_err!(f, "error parsing encoded object"; e), + Unconsumed => write!(f, "data not consumed entirely when deserializing"), Other(ref other) => write!(f, "other decoding error: {:?}", other), } } @@ -82,8 +84,8 @@ impl std::error::Error for DecodeEr use DecodeError::*; match *self { - TooManyBytes => None, - Consensus(ref e) => Some(e), + Parse(ref e) => Some(e), + Unconsumed => None, Other(ref e) => Some(e), } } diff --git a/bitcoin/src/consensus/mod.rs b/bitcoin/src/consensus/mod.rs index 04dbd5479..708ff6347 100644 --- a/bitcoin/src/consensus/mod.rs +++ b/bitcoin/src/consensus/mod.rs @@ -38,12 +38,12 @@ impl>> IterReader { fn decode(mut self) -> Result> { let result = T::consensus_decode(&mut self); match (result, self.error) { - (Ok(_), None) if self.iterator.next().is_some() => Err(DecodeError::TooManyBytes), + (Ok(_), None) if self.iterator.next().is_some() => Err(DecodeError::Unconsumed), (Ok(value), None) => Ok(value), (Ok(_), Some(error)) => panic!("{} silently ate the error: {:?}", core::any::type_name::(), error), (Err(consensus::encode::Error::Io(io_error)), Some(de_error)) if io_error.kind() == io::ErrorKind::Other && io_error.get_ref().is_none() => Err(DecodeError::Other(de_error)), - (Err(consensus_error), None) => Err(DecodeError::Consensus(consensus_error)), + (Err(consensus::encode::Error::Parse(parse_error)), None) => Err(DecodeError::Parse(parse_error)), (Err(consensus::encode::Error::Io(io_error)), de_error) => panic!("unexpected IO error {:?} returned from {}::consensus_decode(), deserialization error: {:?}", io_error, core::any::type_name::(), de_error), (Err(consensus_error), Some(de_error)) => panic!("{} should've returned `Other` IO error because of deserialization error {:?} but it returned consensus error {:?} instead", core::any::type_name::(), de_error, consensus_error), } diff --git a/bitcoin/src/consensus/serde.rs b/bitcoin/src/consensus/serde.rs index 2751098fb..8ef5e275e 100644 --- a/bitcoin/src/consensus/serde.rs +++ b/bitcoin/src/consensus/serde.rs @@ -17,7 +17,7 @@ use serde::de::{SeqAccess, Unexpected, Visitor}; use serde::ser::SerializeSeq; use serde::{Deserializer, Serializer}; -use super::{Decodable, Encodable, Error, ParseError}; +use super::{Decodable, Encodable, ParseError}; use crate::consensus::{DecodeError, IterReader}; /// Hex-encoding strategy @@ -387,10 +387,8 @@ where fn unify(self) -> E { match self { DecodeError::Other(error) => error, - DecodeError::TooManyBytes => E::custom(format_args!("got more bytes than expected")), - DecodeError::Consensus(Error::Parse(e)) => consensus_error_into_serde(e), - DecodeError::Consensus(Error::Io(_)) => - unreachable!("iterator never returns I/O error"), + DecodeError::Unconsumed => E::custom(format_args!("got more bytes than expected")), + DecodeError::Parse(e) => consensus_error_into_serde(e), } } } @@ -402,10 +400,8 @@ where fn into_de_error(self) -> DE { match self { DecodeError::Other(error) => error.into_de_error(), - DecodeError::TooManyBytes => DE::custom(format_args!("got more bytes than expected")), - DecodeError::Consensus(Error::Parse(e)) => consensus_error_into_serde(e), - DecodeError::Consensus(Error::Io(_)) => - unreachable!("iterator never returns I/O error"), + DecodeError::Unconsumed => DE::custom(format_args!("got more bytes than expected")), + DecodeError::Parse(e) => consensus_error_into_serde(e), } } }