Skip to main content

zakura_chain/
error.rs

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