zebra_chain/
error.rs

1//! Errors that can occur inside any `zebra-chain` submodule.
2
3use std::{io, sync::Arc};
4use thiserror::Error;
5
6// TODO: Move all these enums into a common enum at the bottom.
7
8/// Errors related to random bytes generation.
9#[derive(Error, Copy, Clone, Debug, PartialEq, Eq)]
10pub enum RandError {
11    /// Error of the `try_fill_bytes` function.
12    #[error("failed to generate a secure stream of random bytes")]
13    FillBytes,
14}
15
16/// An error type pertaining to shielded notes.
17#[derive(Error, Copy, Clone, Debug, PartialEq, Eq)]
18pub enum NoteError {
19    /// Errors of type `RandError`.
20    #[error("Randomness generation failure")]
21    InsufficientRandomness(#[from] RandError),
22    /// Error of `pallas::Point::from_bytes()` for new rho randomness.
23    #[error("failed to generate an Orchard note's rho.")]
24    InvalidRho,
25}
26
27/// An error type pertaining to note commitments.
28#[derive(Error, Copy, Clone, Debug, PartialEq, Eq)]
29pub enum NoteCommitmentError {
30    /// Errors of type `RandError`.
31    #[error("Randomness generation failure")]
32    InsufficientRandomness(#[from] RandError),
33    /// Error of `jubjub::AffinePoint::try_from`.
34    #[error("failed to generate a sapling::NoteCommitment from a diversifier")]
35    InvalidDiversifier,
36}
37
38/// An error type pertaining to key generation, parsing, modification,
39/// randomization.
40#[derive(Error, Copy, Clone, Debug, PartialEq, Eq)]
41pub enum KeyError {
42    /// Errors of type `RandError`.
43    #[error("Randomness generation failure")]
44    InsufficientRandomness(#[from] RandError),
45}
46
47/// An error type pertaining to payment address generation, parsing,
48/// modification, diversification.
49#[derive(Error, Copy, Clone, Debug, PartialEq, Eq)]
50pub enum AddressError {
51    /// Errors of type `RandError`.
52    #[error("Randomness generation failure")]
53    InsufficientRandomness(#[from] RandError),
54    /// Errors pertaining to diversifier generation.
55    #[error("Randomness did not hash into the Jubjub group for producing a new diversifier")]
56    DiversifierGenerationFailure,
57}
58
59/// `zebra-chain`'s errors
60#[derive(Clone, Error, Debug)]
61pub enum Error {
62    /// Invalid consensus branch ID.
63    #[error("invalid consensus branch id")]
64    InvalidConsensusBranchId,
65
66    /// Zebra's type could not be converted to its librustzcash equivalent.
67    #[error("Zebra's type could not be converted to its librustzcash equivalent: {0}")]
68    Conversion(#[from] Arc<io::Error>),
69
70    /// The transaction is missing a network upgrade.
71    #[error("the transaction is missing a network upgrade")]
72    MissingNetworkUpgrade,
73}
74
75/// Allow converting `io::Error` to `Error`; we need this since we
76/// use `Arc<io::Error>` in `Error::Conversion`.
77impl From<io::Error> for Error {
78    fn from(value: io::Error) -> Self {
79        Arc::new(value).into()
80    }
81}
82
83// We need to implement this manually because io::Error does not implement
84// PartialEq.
85impl PartialEq for Error {
86    fn eq(&self, other: &Self) -> bool {
87        match self {
88            Error::InvalidConsensusBranchId => matches!(other, Error::InvalidConsensusBranchId),
89            Error::Conversion(e) => {
90                if let Error::Conversion(o) = other {
91                    // Not perfect, but good enough for testing, which
92                    // is the main purpose for our usage of PartialEq for errors
93                    e.to_string() == o.to_string()
94                } else {
95                    false
96                }
97            }
98            Error::MissingNetworkUpgrade => matches!(other, Error::MissingNetworkUpgrade),
99        }
100    }
101}
102
103impl Eq for Error {}