1use 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#[derive(Debug, thiserror::Error)]
13pub enum SyncError<E>
14where
15 E: std::fmt::Debug + std::fmt::Display,
16{
17 #[error("mempool error. {0}")]
19 MempoolError(#[from] MempoolError),
20 #[error("scan error. {0}")]
22 ScanError(#[from] ScanError),
23 #[error("server error. {0}")]
25 ServerError(#[from] ServerError),
26 #[error("sync mode error. {0}")]
28 SyncModeError(#[from] SyncModeError),
29 #[error("wallet height is more than {0} blocks ahead of best chain height")]
31 ChainError(u32),
32 #[error("shard tree error. {0}")]
34 ShardTreeError(#[from] ShardTreeError<Infallible>),
35 #[error("transparent address derivation error. {0}")]
37 TransparentAddressDerivationError(bip32::Error),
38 #[error("wallet error. {0}")]
40 WalletError(E),
41}
42
43#[derive(Debug, thiserror::Error)]
45pub enum SyncStatusError<E>
46where
47 E: std::fmt::Debug + std::fmt::Display,
48{
49 #[error("No sync data. Wallet has never been synced with the block chain.")]
51 NoSyncData,
52 #[error("wallet error. {0}")]
54 WalletError(E),
55}
56
57#[derive(Debug, thiserror::Error)]
59pub enum MempoolError {
60 #[error("server error. {0}")]
62 ServerError(#[from] ServerError),
63 #[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#[derive(Debug, thiserror::Error)]
72pub enum ScanError {
73 #[error("server error. {0}")]
75 ServerError(#[from] ServerError),
76 #[error("continuity error. {0}")]
78 ContinuityError(#[from] ContinuityError),
79 #[error("{0}")]
81 ZcbScanError(zcash_client_backend::scanning::ScanError),
82 #[error("invalid sapling nullifier. {0}")]
84 InvalidSaplingNullifier(#[from] TryFromSliceError),
85 #[error("invalid orchard nullifier length. should be 32 bytes, found {0}")]
87 InvalidOrchardNullifierLength(usize),
88 #[error("invalid orchard nullifier")]
90 InvalidOrchardNullifier,
91 #[error("invalid sapling output")]
94 InvalidSaplingOutput,
95 #[error("invalid orchard action")]
98 InvalidOrchardAction,
99 #[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: PoolType,
106 block_metadata_size: u32,
108 calculated_size: u32,
110 },
111 #[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: TxId,
118 txid_returned: TxId,
120 },
121 #[error("decrypted note nullifier and position data not found. output id: {0:?}")]
123 DecryptedNoteDataNotFound(OutputId),
124 #[error("invalid memo bytes. {0}")]
126 InvalidMemoBytes(#[from] zcash_primitives::memo::Error),
127 #[error("failed to parse encoded address. {0}")]
129 AddressParseError(#[from] zcash_address::unified::ParseError),
130}
131
132#[derive(Debug, thiserror::Error)]
134pub enum ContinuityError {
135 #[error(
137 "height discontinuity. block with height {height} is not continuous with previous block height {previous_block_height}"
138 )]
139 HeightDiscontinuity {
140 height: BlockHeight,
142 previous_block_height: BlockHeight,
144 },
145 #[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 height: BlockHeight,
152 prev_hash: BlockHash,
154 previous_block_hash: BlockHash,
156 },
157}
158
159#[derive(Debug, thiserror::Error)]
163pub enum ServerError {
164 #[error("server request failed. {0}")]
166 RequestFailed(#[from] tonic::Status),
167 #[error("server returned invalid frontier. {0}")]
169 InvalidFrontier(std::io::Error),
170 #[error("server returned invalid transaction. {0}")]
172 InvalidTransaction(std::io::Error),
173 #[error("server returned invalid subtree root")]
176 InvalidSubtreeRoot,
177 #[error(
179 "server returned blocks that could not be verified against wallet block data. exceeded max verification window."
180 )]
181 ChainVerificationError,
182}
183
184#[derive(Debug, thiserror::Error)]
186pub enum SyncModeError {
187 #[error("invalid sync mode. {0}")]
189 InvalidSyncMode(u8),
190 #[error("sync is already running")]
192 SyncAlreadyRunning,
193 #[error("sync is not running")]
195 SyncNotRunning,
196 #[error("sync is not paused")]
198 SyncNotPaused,
199}