Skip to main content

kinetic_core/
error.rs

1//! Unified error taxonomy and logbook registry for Kinetic.
2//!
3//! All errors in Kinetic follow a domain-specific hierarchy designed to prevent
4//! raw OS error leakage, enforce RFC 7807 problem details URIs, and supply clean
5//! user-facing messages.
6//!
7//! ## Kinetic Error Taxonomy Architecture
8//!
9//! Every specialized domain error (e.g. [`ResolutionError`], [`PublishError`], [`RegistrationError`])
10//! provides a rich metadata interface:
11//!
12//! 1. **Stable Protocol Code**: Unique string code (e.g. `KIN-RES-001`, `KIN-PUB-003`, `KIN-REG-005`).
13//! 2. **RFC 7807 Type URI**: Web specification URI for standard error documentation.
14//! 3. **Retryability Flag** ([`is_retryable`](ResolutionError::is_retryable)): Indicates if clients should retry.
15//! 4. **Severity Classifier** ([`Severity`]): Directs logging and alert levels (`Info`, `Warning`, `Error`, `Critical`).
16//! 5. **User Message** ([`user_message`](ResolutionError::user_message)): Clean, non-technical explanation for UIs.
17//! 6. **Developer Details** ([`details`](ResolutionError::details)): Structured JSON payload for API extractors.
18//!
19//! ## Error Code Namespaces
20//!
21//! | Prefix | Error Type | Domain |
22//! |---|---|---|
23//! | `KIN-RES-NNN` | [`ResolutionError`] | DHT name resolution |
24//! | `KIN-PUB-NNN` | [`PublishError`] | DHT record publishing |
25//! | `KIN-REG-NNN` | [`RegistrationError`] | Name registration flow |
26//! | `KIN-VDF-NNN` | `VdfError` | VDF engine operations |
27//! | `KIN-GOV-NNN` | `GovernanceError` | Council governance |
28//! | `KIN-DNS-NNN` | `DnsError` | DNS zone parsing |
29//! | `KIN-DRA-NNN` | `DrandError` | Drand beacon |
30//! | `KIN-IDN-NNN` | `IdentityError` | Node identity keys |
31//! | `KIN-NAM-NNN` | `NamesError` | Name validation |
32//! | `KIN-STO-NNN` | `StorageError` | Sled storage engine |
33//! | `KIN-NET-NNN` | `NetworkClientError` + `KineticStoreError` | P2P network client and store layer |
34
35use thiserror::Error;
36
37/// DHT record rejection and resolution/publish/registration error types.
38pub mod dht;
39/// DNS Zone parsing and validation error types.
40pub mod dns;
41/// Drand Quicknet kyn acquisition and verification error types.
42pub mod drand;
43/// Council governance and parameter-update error types.
44pub mod governance;
45/// Node identity and seed phrase error types.
46pub mod identity;
47/// Name validation error types (`KIN-NAM-NNN`).
48pub mod names;
49/// libp2p network client error types.
50pub mod network;
51/// Sled storage engine error types.
52pub mod storage;
53
54/// chiavdf Verifiable Delay Function error types.
55pub mod vdf;
56
57pub use dht::{PublishError, RecordRejectReason, RegistrationError, ResolutionError};
58pub use dns::DnsError;
59pub use drand::DrandError;
60pub use governance::GovernanceError;
61pub use identity::IdentityError;
62pub use names::NamesError;
63pub use network::NetworkClientError;
64pub use storage::StorageError;
65pub use vdf::{VdfError, VdfRejectReason};
66
67/// Top-level error type for core Kinetic protocol operations.
68///
69/// Encapsulates all subsystem errors into a single unified enum used across
70/// core kernel API boundaries. Subsystem-specific errors should be used directly
71/// inside their respective modules; this type is for cross-cutting operations
72/// that span multiple domains.
73///
74/// # Protocol Context
75///
76/// This is the "catch-all" error type at kernel boundaries. Callers in `kinetic-daemon`
77/// and `kinetic-network` that cross subsystem lines use this type. For richer context
78/// (error codes, retryability, user messages), prefer the domain-specific error types.
79#[derive(Error, Debug)]
80pub enum KineticError {
81    /// A VDF proof did not meet the required difficulty target.
82    ///
83    /// Raised when a Wesolowski VDF proof is structurally invalid or does not
84    /// verify against its challenge hash. See [`VdfError`] for finer-grained variants.
85    #[error("VDF proof verification failed")]
86    InvalidVdfProof,
87
88    /// Name validation failed.
89    ///
90    /// Wraps [`NamesError`] for names that violate LDH rules, exceed length limits,
91    /// match reserved names (RFC 2606/6761), or are not apex names.
92    #[error("Invalid Name: {0}")]
93    InvalidName(#[from] NamesError),
94
95    /// An Ed25519 or ML-DSA-65 signature failed verification.
96    ///
97    /// Ed25519 signatures are used for DHT record ownership (reveal records).
98    /// ML-DSA-65 signatures are used for the daemon identity and governance actions.
99    #[error("Signature verification failed")]
100    InvalidSignature,
101
102    /// The revealed data's hash does not match the previously published commitment.
103    ///
104    /// Protocol invariant: a reveal is only accepted if
105    /// `SHA-256(name || salt || payload) == stored_commitment_hash`. This variant
106    /// fires when that invariant is violated.
107    #[error("Hash commitment mismatch: revealed data does not match commitment")]
108    CommitmentMismatch,
109
110    /// A drand kyn was rejected as invalid.
111    ///
112    /// Raised when the kyn kyn number is wrong, the hex encoding is malformed,
113    /// or the BLS signature does not verify against the Quicknet chain public key.
114    #[error("Invalid Drand kyn: {0}")]
115    InvalidDrandPulse(String),
116
117    /// A storage operation in Sled failed.
118    ///
119    /// Wraps the underlying Sled error message as a string to avoid propagating
120    /// the sled crate type across the API boundary.
121    #[error("Storage layer error: {0}")]
122    StorageError(String),
123
124    /// An unexpected internal engine failure.
125    ///
126    /// Used only for truly unrecoverable states. Prefer domain-specific error
127    /// variants for expected failure modes.
128    #[error("Internal engine error: {0}")]
129    Internal(String),
130
131    /// An OS I/O failure.
132    ///
133    /// Wraps [`std::io::Error`] directly for cases where file or socket I/O
134    /// fails at a level below any domain-specific handler.
135    #[error("I/O error: {0}")]
136    Io(#[from] std::io::Error),
137
138    /// A configuration value was missing or invalid.
139    ///
140    /// Raised by [`KineticConfig::load`](crate::config::KineticConfig::load) on
141    /// parse failures and by startup validation when required fields are absent.
142    #[error("Configuration error: {0}")]
143    ConfigError(String),
144
145    /// A cryptographic operation failed.
146    ///
147    /// Covers hashing, key derivation, discriminant generation, and other
148    /// operations that are not covered by [`InvalidSignature`](Self::InvalidSignature).
149    #[error("Cryptographic operation failed: {0}")]
150    CryptoError(String),
151
152    /// A P2P network interaction failed.
153    ///
154    /// Wraps the network client error message. For richer context use
155    /// [`NetworkClientError`] directly from `kinetic-network`.
156    #[error("Network interaction failed: {0}")]
157    NetworkError(String),
158}
159
160// ─── Severity ─────────────────────────────────────────────────────────────────
161
162/// Alert and logging severity level for a Kinetic error.
163///
164/// Every domain error type implements a `severity()` method returning one of
165/// these variants. The severity drives log level selection in
166/// `KineticStoreError::log_warning` and alert routing in monitoring pipelines.
167///
168/// # Operational Meaning
169///
170/// | Variant | Log Level | Action Required |
171/// |---|---|---|
172/// | `Info` | `tracing::info!` | Normal protocol outcome; no action needed |
173/// | `Warning` | `tracing::warn!` | Transient or expected condition; monitor |
174/// | `Error` | `tracing::error!` | Unexpected failure; investigate |
175/// | `Critical` | `tracing::error!` | Security or liveness threat; page on-call |
176///
177///
178#[derive(Debug, Clone, Copy, PartialEq, Eq)]
179pub enum Severity {
180    /// Expected protocol outcome — not a system problem.
181    ///
182    /// Examples: name not found in DHT, commitment too recent, tie-break lost.
183    Info,
184    /// Transient condition expected to self-recover.
185    ///
186    /// Examples: peer disconnect, query timeout, rate-limit hit.
187    Warning,
188    /// Unexpected failure requiring investigation.
189    ///
190    /// Examples: invalid VDF proof received, corrupt record, bad signature.
191    Error,
192    /// Security-critical failure requiring immediate response.
193    ///
194    /// Examples: governance key missing, VDF unsupported on platform,
195    /// node cannot participate in network operations.
196    Critical,
197}