use std::net::SocketAddr;
use thiserror::Error;
pub type Result<T> = std::result::Result<T, ChaincraftError>;
#[derive(Error, Debug)]
pub enum ChaincraftError {
#[error("Network error: {0}")]
Network(#[from] NetworkError),
#[error("Cryptographic error: {0}")]
Crypto(#[from] CryptoError),
#[error("Storage error: {0}")]
Storage(#[from] StorageError),
#[error("Serialization error: {0}")]
Serialization(#[from] SerializationError),
#[error("Validation error: {0}")]
Validation(String),
#[error("Consensus error: {0}")]
Consensus(String),
#[error("Configuration error: {0}")]
Config(String),
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
#[error("{0}")]
Generic(String),
}
#[derive(Error, Debug)]
pub enum NetworkError {
#[error("Failed to bind to {addr}: {source}")]
BindFailed {
addr: SocketAddr,
source: std::io::Error,
},
#[error("Failed to connect to {addr}: {source}")]
ConnectionFailed {
addr: SocketAddr,
source: std::io::Error,
},
#[error("Peer {addr} is banned until {expires_at}")]
PeerBanned {
addr: SocketAddr,
expires_at: chrono::DateTime<chrono::Utc>,
},
#[error("Message size {size} exceeds maximum {max_size}")]
MessageTooLarge { size: usize, max_size: usize },
#[error("Invalid message format: {reason}")]
InvalidMessage { reason: String },
#[error("Operation timed out after {duration:?}")]
Timeout { duration: std::time::Duration },
#[error("No peers available for operation")]
NoPeersAvailable,
}
#[derive(Error, Debug)]
pub enum CryptoError {
#[error("Invalid signature")]
InvalidSignature,
#[error("Invalid public key: {reason}")]
InvalidPublicKey { reason: String },
#[error("Invalid private key: {reason}")]
InvalidPrivateKey { reason: String },
#[error("Hash verification failed")]
HashVerificationFailed,
#[error("Proof of work verification failed")]
ProofOfWorkFailed,
#[error("VRF verification failed")]
VrfVerificationFailed,
#[error("VDF verification failed")]
VdfVerificationFailed,
#[error("VDF error: {reason}")]
VdfError { reason: String },
#[error("Key generation failed: {reason}")]
KeyGenerationFailed { reason: String },
#[error("Encryption failed: {reason}")]
EncryptionFailed { reason: String },
#[error("Decryption failed: {reason}")]
DecryptionFailed { reason: String },
}
#[derive(Error, Debug)]
pub enum StorageError {
#[error("Database operation failed: {reason}")]
DatabaseOperation { reason: String },
#[error("Key not found: {key}")]
KeyNotFound { key: String },
#[error("Failed to serialize data: {reason}")]
SerializationFailed { reason: String },
#[error("Failed to deserialize data: {reason}")]
DeserializationFailed { reason: String },
#[error("Database corruption detected: {reason}")]
Corruption { reason: String },
#[error("Attempted to write to read-only database")]
ReadOnly,
#[error("Transaction failed: {reason}")]
TransactionFailed { reason: String },
}
#[derive(Error, Debug)]
pub enum SerializationError {
#[error("JSON error: {0}")]
Json(#[from] serde_json::Error),
#[error("Binary serialization error: {0}")]
Binary(#[from] bincode::Error),
#[error("Invalid message format: expected {expected}, got {actual}")]
InvalidFormat { expected: String, actual: String },
#[error("Missing required field: {field}")]
MissingField { field: String },
#[error("Field validation failed for {field}: {reason}")]
FieldValidation { field: String, reason: String },
}
impl ChaincraftError {
pub fn validation<T: Into<String>>(msg: T) -> Self {
ChaincraftError::Validation(msg.into())
}
pub fn consensus<T: Into<String>>(msg: T) -> Self {
ChaincraftError::Consensus(msg.into())
}
pub fn config<T: Into<String>>(msg: T) -> Self {
ChaincraftError::Config(msg.into())
}
pub fn generic<T: Into<String>>(msg: T) -> Self {
ChaincraftError::Generic(msg.into())
}
}
impl From<serde_json::Error> for ChaincraftError {
fn from(err: serde_json::Error) -> Self {
ChaincraftError::Serialization(SerializationError::Json(err))
}
}