1use thiserror::Error;
4use zeroize::{Zeroize, ZeroizeOnDrop};
5
6#[derive(Error, Debug)]
8pub enum ExchangeError {
9 #[error("Cryptographic error: {0}")]
11 Crypto(#[from] qudag_crypto::CryptoError),
12
13 #[error("Vault error: {0}")]
15 Vault(String),
16
17 #[error("Network error: {0}")]
19 Network(String),
20
21 #[error("DAG consensus error: {0}")]
23 Consensus(String),
24
25 #[error("ZKP verification failed: {0}")]
27 ZkpVerification(String),
28
29 #[error("Resource metering error: {0}")]
31 Metering(String),
32
33 #[error("Transaction validation failed: {0}")]
35 TransactionValidation(String),
36
37 #[error("Insufficient rUv credits: required {required}, available {available}")]
39 InsufficientCredits {
40 required: u64,
42 available: u64,
44 },
45
46 #[error("Rate limit exceeded: {0}")]
48 RateLimitExceeded(String),
49
50 #[error("Authentication failed")]
52 AuthenticationFailed,
53
54 #[error("Authorization failed: {0}")]
56 AuthorizationFailed(String),
57
58 #[error("Invalid signature")]
60 InvalidSignature,
61
62 #[error("Timing anomaly detected - potential attack")]
64 TimingAnomaly,
65
66 #[error("Replay attack detected")]
68 ReplayAttack,
69
70 #[error("Double spending attempt detected")]
72 DoubleSpending,
73
74 #[error("Resource exhaustion detected")]
76 ResourceExhaustion,
77
78 #[error("Invalid state transition: {0}")]
80 InvalidStateTransition(String),
81
82 #[error("Serialization error: {0}")]
84 Serialization(String),
85
86 #[error("IO error: {0}")]
88 Io(#[from] std::io::Error),
89
90 #[error("Exchange error: {0}")]
92 Other(String),
93}
94
95#[derive(Debug)]
97pub struct SecureError {
98 inner: String,
99}
100
101impl SecureError {
102 pub fn new(msg: String) -> Self {
104 Self { inner: msg }
105 }
106}
107
108impl Drop for SecureError {
109 fn drop(&mut self) {
110 self.inner.zeroize();
111 }
112}
113
114impl std::fmt::Display for SecureError {
115 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
116 write!(f, "[REDACTED]")
117 }
118}
119
120pub type Result<T> = std::result::Result<T, ExchangeError>;
122
123#[cfg(test)]
124mod tests {
125 use super::*;
126
127 #[test]
128 fn test_secure_error_zeroization() {
129 let mut error = SecureError::new("sensitive data".to_string());
130 drop(error);
131 }
133
134 #[test]
135 fn test_secure_error_display() {
136 let error = SecureError::new("sensitive data".to_string());
137 assert_eq!(format!("{}", error), "[REDACTED]");
138 }
139}