pepper_sync/
error.rs

1//! Pepper sync error module
2
3use std::{array::TryFromSliceError, convert::Infallible};
4
5use shardtree::error::ShardTreeError;
6use zcash_primitives::{block::BlockHash, consensus::BlockHeight, transaction::TxId};
7use zcash_protocol::PoolType;
8
9use crate::wallet::OutputId;
10
11/// Top level error enumerating any error that may occur during sync
12#[derive(Debug, thiserror::Error)]
13pub enum SyncError<E>
14where
15    E: std::fmt::Debug + std::fmt::Display,
16{
17    /// Mempool error.
18    #[error("mempool error. {0}")]
19    MempoolError(#[from] MempoolError),
20    /// Scan error.
21    #[error("scan error. {0}")]
22    ScanError(#[from] ScanError),
23    /// Server error.
24    #[error("server error. {0}")]
25    ServerError(#[from] ServerError),
26    /// Sync mode error.
27    #[error("sync mode error. {0}")]
28    SyncModeError(#[from] SyncModeError),
29    /// Chain error.
30    #[error("wallet height is more than {0} blocks ahead of best chain height")]
31    ChainError(u32),
32    /// Shard tree error.
33    #[error("shard tree error. {0}")]
34    ShardTreeError(#[from] ShardTreeError<Infallible>),
35    /// Transparent address derivation error.
36    #[error("transparent address derivation error. {0}")]
37    TransparentAddressDerivationError(bip32::Error),
38    /// Wallet error.
39    #[error("wallet error. {0}")]
40    WalletError(E),
41}
42
43/// Sync status errors.
44#[derive(Debug, thiserror::Error)]
45pub enum SyncStatusError<E>
46where
47    E: std::fmt::Debug + std::fmt::Display,
48{
49    /// No sync data. Wallet has never been synced with the block chain.
50    #[error("No sync data. Wallet has never been synced with the block chain.")]
51    NoSyncData,
52    /// Wallet error.
53    #[error("wallet error. {0}")]
54    WalletError(E),
55}
56
57/// Mempool errors.
58#[derive(Debug, thiserror::Error)]
59pub enum MempoolError {
60    /// Server error.
61    #[error("server error. {0}")]
62    ServerError(#[from] ServerError),
63    /// Timed out fetching mempool stream during shutdown.
64    #[error(
65        "timed out fetching mempool stream during shutdown.\nNON-CRITICAL: sync completed successfully but may not have scanned transactions in the mempool."
66    )]
67    ShutdownWithoutStream,
68}
69
70/// Scan errors.
71#[derive(Debug, thiserror::Error)]
72pub enum ScanError {
73    /// Server error.
74    #[error("server error. {0}")]
75    ServerError(#[from] ServerError),
76    /// Continuity error.
77    #[error("continuity error. {0}")]
78    ContinuityError(#[from] ContinuityError),
79    /// Zcash client backend scan error
80    #[error("{0}")]
81    ZcbScanError(zcash_client_backend::scanning::ScanError),
82    /// Invalid sapling nullifier
83    #[error("invalid sapling nullifier. {0}")]
84    InvalidSaplingNullifier(#[from] TryFromSliceError),
85    /// Invalid orchard nullifier length
86    #[error("invalid orchard nullifier length. should be 32 bytes, found {0}")]
87    InvalidOrchardNullifierLength(usize),
88    /// Invalid orchard nullifier
89    #[error("invalid orchard nullifier")]
90    InvalidOrchardNullifier,
91    /// Invalid sapling output
92    // TODO: add output data
93    #[error("invalid sapling output")]
94    InvalidSaplingOutput,
95    /// Invalid orchard action
96    // TODO: add output data
97    #[error("invalid orchard action")]
98    InvalidOrchardAction,
99    /// Incorrect tree size
100    #[error(
101        "incorrect tree size. {shielded_protocol} tree size recorded in block metadata {block_metadata_size} does not match calculated size {calculated_size}"
102    )]
103    IncorrectTreeSize {
104        /// Shielded protocol
105        shielded_protocol: PoolType,
106        /// Block metadata size
107        block_metadata_size: u32,
108        /// Calculated size
109        calculated_size: u32,
110    },
111    /// Txid of transaction returned by the server does not match requested txid.
112    #[error(
113        "txid of transaction returned by the server does not match requested txid.\ntxid requested: {txid_requested}\ntxid returned: {txid_returned}"
114    )]
115    IncorrectTxid {
116        /// Txid requested
117        txid_requested: TxId,
118        /// Txid returned
119        txid_returned: TxId,
120    },
121    /// Decrypted note nullifier and position data not found.
122    #[error("decrypted note nullifier and position data not found. output id: {0:?}")]
123    DecryptedNoteDataNotFound(OutputId),
124    /// Invalid memo bytes..
125    #[error("invalid memo bytes. {0}")]
126    InvalidMemoBytes(#[from] zcash_primitives::memo::Error),
127    /// Failed to parse encoded address.
128    #[error("failed to parse encoded address. {0}")]
129    AddressParseError(#[from] zcash_address::unified::ParseError),
130}
131
132/// Block continuity errors.
133#[derive(Debug, thiserror::Error)]
134pub enum ContinuityError {
135    /// Height discontinuity.
136    #[error(
137        "height discontinuity. block with height {height} is not continuous with previous block height {previous_block_height}"
138    )]
139    HeightDiscontinuity {
140        /// Block height
141        height: BlockHeight,
142        /// Previous block height
143        previous_block_height: BlockHeight,
144    },
145    /// Hash discontinuity.
146    #[error(
147        "hash discontinuity. block prev_hash {prev_hash} with height {height} does not match previous block hash {previous_block_hash}"
148    )]
149    HashDiscontinuity {
150        /// Block height
151        height: BlockHeight,
152        /// Block's previous block hash data
153        prev_hash: BlockHash,
154        /// Actual previous block hash
155        previous_block_hash: BlockHash,
156    },
157}
158
159/// Server errors.
160///
161/// Errors associated with connecting to the server and receiving invalid data.
162#[derive(Debug, thiserror::Error)]
163pub enum ServerError {
164    /// Server request failed
165    #[error("server request failed. {0}")]
166    RequestFailed(#[from] tonic::Status),
167    /// Server returned invalid frontier
168    #[error("server returned invalid frontier. {0}")]
169    InvalidFrontier(std::io::Error),
170    /// Server returned invalid transaction
171    #[error("server returned invalid transaction. {0}")]
172    InvalidTransaction(std::io::Error),
173    /// Server returned invalid subtree root
174    // TODO: add more info
175    #[error("server returned invalid subtree root")]
176    InvalidSubtreeRoot,
177    /// Server returned blocks that could not be verified against wallet block data. Exceeded max verification window.
178    #[error(
179        "server returned blocks that could not be verified against wallet block data. exceeded max verification window."
180    )]
181    ChainVerificationError,
182}
183
184/// Sync mode error.
185#[derive(Debug, thiserror::Error)]
186pub enum SyncModeError {
187    /// Invalid sync mode.
188    #[error("invalid sync mode. {0}")]
189    InvalidSyncMode(u8),
190    /// Sync is already running.
191    #[error("sync is already running")]
192    SyncAlreadyRunning,
193    /// Sync is not running.
194    #[error("sync is not running")]
195    SyncNotRunning,
196    /// Sync is not paused.
197    #[error("sync is not paused")]
198    SyncNotPaused,
199}