zebra_chain/serialization/
error.rs

1//! Errors for Zcash consensus-critical serialization.
2
3use std::{array::TryFromSliceError, io, num::TryFromIntError, str::Utf8Error};
4
5use hex::FromHexError;
6use thiserror::Error;
7
8/// A serialization error.
9// TODO: refine error types -- better to use boxed errors?
10#[derive(Error, Debug)]
11pub enum SerializationError {
12    /// An io error that prevented deserialization
13    #[error("io error: {0}")]
14    Io(#[from] io::Error),
15
16    /// The data to be deserialized was malformed.
17    // TODO: refine errors
18    #[error("parse error: {0}")]
19    Parse(&'static str),
20
21    /// A string was not UTF-8.
22    ///
23    /// Note: Rust `String` and `str` are always UTF-8.
24    #[error("string was not UTF-8: {0}")]
25    Utf8Error(#[from] Utf8Error),
26
27    /// A slice was an unexpected length during deserialization.
28    #[error("slice was the wrong length: {0}")]
29    TryFromSliceError(#[from] TryFromSliceError),
30
31    /// The length of a vec is too large to convert to a usize (and thus, too large to allocate on this platform)
32    #[error("CompactSize too large: {0}")]
33    TryFromIntError(#[from] TryFromIntError),
34
35    /// A string was not valid hexadecimal.
36    #[error("string was not hex: {0}")]
37    FromHexError(#[from] FromHexError),
38
39    /// An error caused when validating a zatoshi `Amount`
40    #[error("input couldn't be parsed as a zatoshi `Amount`: {source}")]
41    Amount {
42        /// The source error indicating how the num failed to validate
43        #[from]
44        source: crate::amount::Error,
45    },
46
47    /// Invalid transaction with a non-zero balance and no Sapling shielded spends or outputs.
48    ///
49    /// Transaction does not conform to the Sapling [consensus
50    /// rule](https://zips.z.cash/protocol/protocol.pdf#txnencodingandconsensus).
51    #[error("transaction balance is non-zero but doesn't have Sapling shielded spends or outputs")]
52    BadTransactionBalance,
53}
54
55impl From<crate::Error> for SerializationError {
56    fn from(value: crate::Error) -> Self {
57        match value {
58            crate::Error::InvalidConsensusBranchId => Self::Parse("invalid consensus branch id"),
59            crate::Error::Conversion(e) => Self::Io(e),
60            crate::Error::MissingNetworkUpgrade => Self::Parse("missing network upgrade"),
61        }
62    }
63}