1use core::fmt;
10
11use crate::node_label::NodeLabel;
12use crate::Direction;
13
14#[cfg_attr(test, derive(PartialEq, Eq))]
16#[derive(Debug)]
17pub enum AkdError {
18 TreeNode(TreeNodeError),
20 Directory(DirectoryError),
22 AzksErr(AzksError),
24 Vrf(akd_core::ecvrf::VrfError),
26 Storage(StorageError),
28 AuditErr(AuditorError),
30 Parallelism(ParallelismError),
32 TestErr(String),
34}
35
36impl std::error::Error for AkdError {}
37
38impl From<TreeNodeError> for AkdError {
39 fn from(error: TreeNodeError) -> Self {
40 Self::TreeNode(error)
41 }
42}
43
44impl From<StorageError> for AkdError {
45 fn from(error: StorageError) -> Self {
46 Self::Storage(error)
47 }
48}
49
50impl From<DirectoryError> for AkdError {
51 fn from(error: DirectoryError) -> Self {
52 Self::Directory(error)
53 }
54}
55
56impl From<akd_core::ecvrf::VrfError> for AkdError {
57 fn from(error: akd_core::ecvrf::VrfError) -> Self {
58 Self::Vrf(error)
59 }
60}
61
62impl From<AzksError> for AkdError {
63 fn from(error: AzksError) -> Self {
64 Self::AzksErr(error)
65 }
66}
67
68impl From<AuditorError> for AkdError {
69 fn from(error: AuditorError) -> Self {
70 Self::AuditErr(error)
71 }
72}
73
74impl From<ParallelismError> for AkdError {
75 fn from(error: ParallelismError) -> Self {
76 Self::Parallelism(error)
77 }
78}
79
80impl From<akd_core::verify::VerificationError> for AkdError {
81 fn from(err: akd_core::verify::VerificationError) -> Self {
82 Self::Directory(err.into())
83 }
84}
85
86impl std::fmt::Display for AkdError {
87 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
88 match self {
89 AkdError::TreeNode(err) => {
90 writeln!(f, "AKD Tree Node Error: {err}")
91 }
92 AkdError::Directory(err) => {
93 writeln!(f, "AKD Directory Error: {err}")
94 }
95 AkdError::AzksErr(err) => {
96 writeln!(f, "AKD AZKS Error: {err}")
97 }
98 AkdError::Vrf(err) => {
99 writeln!(f, "AKD VRF Error: {err}")
100 }
101 AkdError::Storage(err) => {
102 writeln!(f, "AKD Storage Error: {err}")
103 }
104 AkdError::AuditErr(err) => {
105 writeln!(f, "AKD Auditor Error {err}")
106 }
107 AkdError::Parallelism(err) => {
108 writeln!(f, "AKD Parallelism Error: {err}")
109 }
110 AkdError::TestErr(err) => {
111 writeln!(f, "{err}")
112 }
113 }
114 }
115}
116
117#[derive(Debug, Eq, PartialEq)]
119pub enum TreeNodeError {
120 InvalidDirection(Direction),
122 NoDirection(NodeLabel, Option<NodeLabel>),
126 NoChildAtEpoch(u64, Direction),
128 ParentNextEpochInvalid(u64),
130 HashUpdateOrderInconsistent,
132 NonexistentAtEpoch(NodeLabel, u64),
134 NoStateAtEpoch(NodeLabel, u64),
136 DigestDeserializationFailed(String),
138}
139
140impl std::error::Error for TreeNodeError {}
141
142impl fmt::Display for TreeNodeError {
143 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
144 match self {
145 Self::InvalidDirection(dir) => {
146 write!(
147 f,
148 "AKD is based on a binary tree. No child with a given direction: {dir:?}"
149 )
150 }
151 Self::NoDirection(node_label, child_label) => {
152 let mut to_print = format!("no direction provided for the node {node_label:?}");
153 if let Some(child_label) = child_label {
155 let child_str = format!(" and child {child_label:?}");
156 to_print.push_str(&child_str);
157 }
158 write!(f, "{to_print}")
159 }
160 Self::NoChildAtEpoch(epoch, direction) => {
161 write!(f, "no node in direction {direction:?} at epoch {epoch}")
162 }
163 Self::ParentNextEpochInvalid(epoch) => {
164 write!(f, "Next epoch of parent is invalid, epoch = {epoch}")
165 }
166 Self::HashUpdateOrderInconsistent => {
167 write!(
168 f,
169 "Hash update in parent only allowed after node is inserted"
170 )
171 }
172 Self::NonexistentAtEpoch(label, epoch) => {
173 write!(
174 f,
175 "This node, labelled {label:?}, did not exist at epoch {epoch:?}."
176 )
177 }
178 Self::NoStateAtEpoch(label, epoch) => {
179 write!(
180 f,
181 "This node, labelled {label:?}, did not exist at epoch {epoch:?}."
182 )
183 }
184 Self::DigestDeserializationFailed(inner_error) => {
185 write!(f, "Encountered a serialization error {inner_error}")
186 }
187 }
188 }
189}
190
191#[cfg_attr(test, derive(PartialEq, Eq))]
193#[derive(Debug)]
194pub enum AzksError {
195 VerifyMembershipProof(String),
197 VerifyAppendOnlyProof(String),
199 NoEpochGiven,
201}
202
203impl std::error::Error for AzksError {}
204
205impl fmt::Display for AzksError {
206 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
207 match self {
208 Self::VerifyMembershipProof(error_string) => {
209 write!(f, "{error_string}")
210 }
211 Self::VerifyAppendOnlyProof(error_string) => {
212 write!(f, "Append only proof did not verify: {error_string}")
213 }
214 Self::NoEpochGiven => {
215 write!(f, "An epoch was required but not supplied")
216 }
217 }
218 }
219}
220
221#[cfg_attr(test, derive(PartialEq, Eq))]
223#[derive(Debug)]
224pub enum DirectoryError {
225 Verification(akd_core::verify::VerificationError),
227 InvalidEpoch(String),
229 ReadOnlyDirectory(String),
231 Publish(String),
233 InvalidVersion(String),
235}
236
237impl std::error::Error for DirectoryError {}
238
239impl fmt::Display for DirectoryError {
240 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
241 match self {
242 Self::Verification(err) => {
243 write!(f, "Verification failure {err}")
244 }
245 Self::InvalidEpoch(err_string) => {
246 write!(f, "Invalid epoch {err_string}")
247 }
248 Self::ReadOnlyDirectory(inner_message) => {
249 write!(f, "Directory in read-only mode: {inner_message}")
250 }
251 Self::Publish(inner_message) => {
252 write!(f, "Directory publish error: {inner_message}")
253 }
254 Self::InvalidVersion(inner_message) => {
255 write!(f, "Invalid version error: {inner_message}")
256 }
257 }
258 }
259}
260
261impl From<akd_core::verify::VerificationError> for DirectoryError {
262 fn from(err: akd_core::verify::VerificationError) -> Self {
263 Self::Verification(err)
264 }
265}
266
267#[cfg_attr(any(test, feature = "public_tests"), derive(PartialEq, Eq))]
269#[derive(Debug)]
270pub enum StorageError {
271 NotFound(String),
273 Transaction(String),
275 Connection(String),
277 Other(String),
279}
280
281impl std::error::Error for StorageError {}
282
283impl fmt::Display for StorageError {
284 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
285 match self {
286 StorageError::Connection(inner) => {
287 write!(f, "Storage connection: {inner}")
288 }
289 StorageError::Transaction(inner) => {
290 write!(f, "Transaction: {inner}")
291 }
292 StorageError::NotFound(inner) => {
293 write!(f, "Data not found: {inner}")
294 }
295 StorageError::Other(inner) => {
296 write!(f, "Other storage error: {inner}")
297 }
298 }
299 }
300}
301
302#[cfg_attr(test, derive(PartialEq, Eq))]
304#[derive(Debug)]
305pub enum AuditorError {
306 VerifyAuditProof(String),
308}
309
310impl std::error::Error for AuditorError {}
311
312impl fmt::Display for AuditorError {
313 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
314 match self {
315 Self::VerifyAuditProof(err_string) => {
316 write!(f, "Failed to verify audit {err_string}")
317 }
318 }
319 }
320}
321
322#[cfg_attr(test, derive(PartialEq, Eq))]
324#[derive(Debug)]
325pub enum ParallelismError {
326 JoinErr(String),
328}
329
330impl std::error::Error for ParallelismError {}
331
332impl fmt::Display for ParallelismError {
333 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
334 match self {
335 Self::JoinErr(err_string) => {
336 write!(f, "Failed to join tokio task {err_string}")
337 }
338 }
339 }
340}