1use crate::{NetworkAddress, PrettyPrintRecordKey};
10use libp2p::kad::store;
11use serde::{Deserialize, Serialize};
12use thiserror::Error;
13
14pub type Result<T> = std::result::Result<T, Error>;
16
17#[derive(Error, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
29#[non_exhaustive]
30pub enum Error {
31 #[error("Chunk does not exist {0:?}")]
33 ChunkDoesNotExist(NetworkAddress),
34
35 #[error("Failed to derive CipherText from encrypted_data")]
38 ScratchpadCipherTextFailed,
39 #[error("Provided cypher text is invalid")]
41 ScratchpadCipherTextInvalid,
42
43 #[error("There was an error getting the storecost from kademlia store")]
45 GetStoreQuoteFailed,
46 #[error("There was an error generating the payment quote")]
47 QuoteGenerationFailed,
48
49 #[error("Peer {holder:?} cannot find Record {key:?}")]
52 ReplicatedRecordNotFound {
53 holder: Box<NetworkAddress>,
55 key: Box<NetworkAddress>,
57 },
58
59 #[error("Could not Serialize/Deserialize RecordHeader to/from Record")]
62 RecordHeaderParsingFailed,
63 #[error("Could not Serialize/Deserialize Record")]
65 RecordParsingFailed,
66 #[error("The record already exists, so do not charge for it: {0:?}")]
68 RecordExists(PrettyPrintRecordKey<'static>),
69
70 #[error("Error handling record put: {0}")]
72 PutRecordFailed(String),
73 #[error("Outdated record: with counter {counter}, expected any above {expected}")]
74 OutdatedRecordCounter { counter: u64, expected: u64 },
75
76 #[error("Unknown error: the peer and you are using different protocol versions")]
80 #[serde(other)]
81 Unknown,
82}
83
84impl From<Error> for store::Error {
85 fn from(_err: Error) -> Self {
86 store::Error::ValueTooLarge
87 }
88}
89
90impl From<store::Error> for Error {
91 fn from(_err: store::Error) -> Self {
92 Error::RecordParsingFailed
93 }
94}
95
96#[cfg(test)]
97mod tests {
98 use libp2p::PeerId;
99
100 use super::*;
101
102 #[test]
103 fn test_error_retro_compatibility() {
104 #[derive(Error, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
106 #[non_exhaustive]
107 enum ExtendedError {
108 #[error("Chunk does not exist {0:?}")]
109 ChunkDoesNotExist(NetworkAddress),
110 #[error("Failed to deserialize hex ScratchpadAddress")]
111 ScratchpadHexDeserializeFailed,
112 #[error("Failed to derive CipherText from encrypted_data")]
113 ScratchpadCipherTextFailed,
114 #[error("Provided cypher text is invalid")]
115 ScratchpadCipherTextInvalid,
116 #[error("There was an error getting the storecost from kademlia store")]
117 GetStoreQuoteFailed,
118 #[error("There was an error generating the payment quote")]
119 QuoteGenerationFailed,
120 #[error("Peer {holder:?} cannot find Record {key:?}")]
121 ReplicatedRecordNotFound {
122 holder: Box<NetworkAddress>,
123 key: Box<NetworkAddress>,
124 },
125 #[error("Could not Serialize/Deserialize RecordHeader to/from Record")]
126 RecordHeaderParsingFailed,
127 #[error("Could not Serialize/Deserialize Record")]
128 RecordParsingFailed,
129 #[error("The record already exists, so do not charge for it: {0:?}")]
130 RecordExists(PrettyPrintRecordKey<'static>),
131 #[error("New error variant for testing")]
133 NewErrorVariant,
134 #[error("Unknown error variant")]
135 #[serde(other)]
136 Unknown,
137 }
138
139 let extended_error = ExtendedError::NewErrorVariant;
141 let serialized = rmp_serde::to_vec(&extended_error).unwrap();
142
143 let deserialized: Error = rmp_serde::from_slice(&serialized).unwrap();
145 assert_eq!(deserialized, Error::Unknown);
146 }
147
148 #[test]
149 fn test_error_retro_compatibility_reduced() {
150 #[derive(Error, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
152 #[non_exhaustive]
153 enum ReducedError {
154 #[error("Chunk does not exist {0:?}")]
155 ChunkDoesNotExist(NetworkAddress),
156 #[error("Failed to deserialize hex ScratchpadAddress")]
157 ScratchpadHexDeserializeFailed,
158 #[error("Provided cypher text is invalid")]
162 ScratchpadCipherTextInvalid,
163 #[error("There was an error getting the storecost from kademlia store")]
164 GetStoreQuoteFailed,
165 #[error("There was an error generating the payment quote")]
166 QuoteGenerationFailed,
167 #[error("Peer {holder:?} cannot find Record {key:?}")]
168 ReplicatedRecordNotFound {
169 holder: Box<NetworkAddress>,
170 key: Box<NetworkAddress>,
171 },
172 #[error("Could not Serialize/Deserialize RecordHeader to/from Record")]
173 RecordHeaderParsingFailed,
174 #[error("Could not Serialize/Deserialize Record")]
175 RecordParsingFailed,
176 #[error("The record already exists, so do not charge for it: {0:?}")]
177 RecordExists(PrettyPrintRecordKey<'static>),
178 #[error("Unknown error variant")]
180 #[serde(other)]
181 Unknown,
182 }
183
184 let current_error = Error::ScratchpadCipherTextInvalid;
186 let serialized_current = rmp_serde::to_vec(¤t_error).unwrap();
187
188 let deserialized_reduced: ReducedError =
190 rmp_serde::from_slice(&serialized_current).unwrap();
191 assert_eq!(
192 deserialized_reduced,
193 ReducedError::ScratchpadCipherTextInvalid
194 );
195
196 let unknown_variant = Error::ScratchpadCipherTextFailed;
198 let serialized_unknown = rmp_serde::to_vec(&unknown_variant).unwrap();
199 let deserialized_unknown: ReducedError =
200 rmp_serde::from_slice(&serialized_unknown).unwrap();
201 assert_eq!(deserialized_unknown, ReducedError::Unknown);
202
203 let reduced_simple_error = ReducedError::GetStoreQuoteFailed;
205 let serialized_reduced_simple = rmp_serde::to_vec(&reduced_simple_error).unwrap();
206 let deserialized_reduced_simple: Error =
207 rmp_serde::from_slice(&serialized_reduced_simple).unwrap();
208 assert_eq!(deserialized_reduced_simple, Error::GetStoreQuoteFailed);
209
210 let addr = NetworkAddress::from(PeerId::random());
212 let reduced_complex_error = ReducedError::ChunkDoesNotExist(addr.clone());
213 let serialized_reduced_complex = rmp_serde::to_vec(&reduced_complex_error).unwrap();
214 let deserialized_reduced_complex: Error =
215 rmp_serde::from_slice(&serialized_reduced_complex).unwrap();
216 assert_eq!(deserialized_reduced_complex, Error::ChunkDoesNotExist(addr));
217
218 let holder = NetworkAddress::from(PeerId::random());
220 let key = NetworkAddress::from(PeerId::random());
221 let reduced_struct_error = ReducedError::ReplicatedRecordNotFound {
222 holder: Box::new(holder.clone()),
223 key: Box::new(key.clone()),
224 };
225 let serialized_reduced_struct = rmp_serde::to_vec(&reduced_struct_error).unwrap();
226 let deserialized_reduced_struct: Error =
227 rmp_serde::from_slice(&serialized_reduced_struct).unwrap();
228 assert_eq!(
229 deserialized_reduced_struct,
230 Error::ReplicatedRecordNotFound {
231 holder: Box::new(holder),
232 key: Box::new(key),
233 }
234 );
235 }
236
237 #[test]
238 fn test_error_retro_compatibility_many_missing() {
239 #[derive(Error, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
241 #[non_exhaustive]
242 enum ManyMissingVariants {
243 #[error("Chunk does not exist {0:?}")]
244 ChunkDoesNotExist(NetworkAddress),
245 #[error("There was an error getting the storecost from kademlia store")]
246 GetStoreQuoteFailed,
247 #[error("Unknown error variant")]
249 #[serde(other)]
250 Unknown,
251 }
252
253 let current_error = Error::ScratchpadCipherTextInvalid;
255 let serialized_current = rmp_serde::to_vec(¤t_error).unwrap();
256 let deserialized_many_missing: ManyMissingVariants =
257 rmp_serde::from_slice(&serialized_current).unwrap();
258 assert_eq!(deserialized_many_missing, ManyMissingVariants::Unknown);
259
260 let chunk_error = Error::GetStoreQuoteFailed;
262 let serialized_chunk = rmp_serde::to_vec(&chunk_error).unwrap();
263 let deserialized_chunk: ManyMissingVariants =
264 rmp_serde::from_slice(&serialized_chunk).unwrap();
265 assert_eq!(deserialized_chunk, ManyMissingVariants::GetStoreQuoteFailed);
266
267 let many_missing_error = ManyMissingVariants::GetStoreQuoteFailed;
269 let serialized_many_missing = rmp_serde::to_vec(&many_missing_error).unwrap();
270 let deserialized_to_error: Error = rmp_serde::from_slice(&serialized_many_missing).unwrap();
271 assert_eq!(deserialized_to_error, Error::GetStoreQuoteFailed);
272
273 let addr = NetworkAddress::from(PeerId::random());
275
276 let chunk_error = Error::ChunkDoesNotExist(addr.clone());
278 let serialized_chunk = rmp_serde::to_vec(&chunk_error).unwrap();
279 let deserialized_chunk: ManyMissingVariants =
280 rmp_serde::from_slice(&serialized_chunk).unwrap();
281 assert_eq!(
282 deserialized_chunk,
283 ManyMissingVariants::ChunkDoesNotExist(addr.clone())
284 );
285
286 let many_missing_chunk = ManyMissingVariants::ChunkDoesNotExist(addr.clone());
288 let serialized_many_missing_chunk = rmp_serde::to_vec(&many_missing_chunk).unwrap();
289 let deserialized_many_missing_chunk: Error =
290 rmp_serde::from_slice(&serialized_many_missing_chunk).unwrap();
291 assert_eq!(
292 deserialized_many_missing_chunk,
293 Error::ChunkDoesNotExist(addr)
294 );
295
296 let record_error = Error::RecordParsingFailed;
298 let serialized_record = rmp_serde::to_vec(&record_error).unwrap();
299 let deserialized_record: ManyMissingVariants =
300 rmp_serde::from_slice(&serialized_record).unwrap();
301 assert_eq!(deserialized_record, ManyMissingVariants::Unknown);
302 }
303
304 #[test]
306 fn test_error_retro_compatibility_complex_types() {
307 #[derive(Error, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
309 #[non_exhaustive]
310 enum ComplexTypesRemoved {
311 #[error("Chunk does not exist {0:?}")]
312 ChunkDoesNotExist(NetworkAddress),
313 #[error("Failed to deserialize hex ScratchpadAddress")]
314 ScratchpadHexDeserializeFailed,
315 #[error("Failed to derive CipherText from encrypted_data")]
316 ScratchpadCipherTextFailed,
317 #[error("Provided cypher text is invalid")]
318 ScratchpadCipherTextInvalid,
319 #[error("There was an error getting the storecost from kademlia store")]
320 GetStoreQuoteFailed,
321 #[error("There was an error generating the payment quote")]
322 QuoteGenerationFailed,
323 #[error("Could not Serialize/Deserialize RecordHeader to/from Record")]
330 RecordHeaderParsingFailed,
331 #[error("Could not Serialize/Deserialize Record")]
332 RecordParsingFailed,
333 #[error("The record already exists, so do not charge for it: {0:?}")]
334 RecordExists(PrettyPrintRecordKey<'static>),
335 #[error("Unknown error variant")]
337 #[serde(other)]
338 Unknown,
339 }
340
341 let holder = NetworkAddress::from(PeerId::random());
344 let key = NetworkAddress::from(PeerId::random());
345 let complex_error = Error::ReplicatedRecordNotFound {
346 holder: Box::new(holder),
347 key: Box::new(key),
348 };
349 let serialized_complex = rmp_serde::to_vec(&complex_error).unwrap();
350
351 assert!(rmp_serde::from_slice::<ComplexTypesRemoved>(&serialized_complex).is_err());
357
358 let simple_error = Error::ScratchpadCipherTextInvalid;
360 let serialized_simple = rmp_serde::to_vec(&simple_error).unwrap();
361 let deserialized_simple: ComplexTypesRemoved =
362 rmp_serde::from_slice(&serialized_simple).unwrap();
363 assert_eq!(
364 deserialized_simple,
365 ComplexTypesRemoved::ScratchpadCipherTextInvalid
366 );
367
368 let addr = NetworkAddress::from(PeerId::random());
370 let chunk_error = Error::ChunkDoesNotExist(addr.clone());
371 let serialized_chunk = rmp_serde::to_vec(&chunk_error).unwrap();
372 let deserialized_chunk: ComplexTypesRemoved =
373 rmp_serde::from_slice(&serialized_chunk).unwrap();
374 assert_eq!(
375 deserialized_chunk,
376 ComplexTypesRemoved::ChunkDoesNotExist(addr)
377 );
378 }
379}