Skip to main content

ethrex_p2p/rlpx/
error.rs

1use super::{message::Message, p2p::DisconnectReason};
2use crate::snap::error::SnapError;
3use aes::cipher::InvalidLength;
4use ethrex_blockchain::error::{ChainError, MempoolError};
5use ethrex_rlp::error::{RLPDecodeError, RLPEncodeError};
6use ethrex_storage::error::StoreError;
7#[cfg(feature = "l2")]
8use ethrex_storage_rollup::RollupStoreError;
9use spawned_concurrency::error::ActorError;
10use thiserror::Error;
11
12#[derive(Debug, Error)]
13pub enum CryptographyError {
14    #[error("Invalid key: {0}")]
15    InvalidKey(String),
16    #[error("Invalid generated secret: {0}")]
17    InvalidGeneratedSecret(String),
18    #[error("Couldn't get keys from shared secret: {0}")]
19    CouldNotGetKeyFromSecret(String),
20}
21
22// TODO improve errors
23#[derive(Debug, Error)]
24pub enum PeerConnectionError {
25    #[error("{0}")]
26    HandshakeError(String),
27    #[error("Invalid connection state: {0}")]
28    StateError(String),
29    #[error("No matching capabilities")]
30    NoMatchingCapabilities,
31    #[error("Too many peers")]
32    TooManyPeers,
33    #[error("Outbound send to peer timed out")]
34    OutboundSendTimeout,
35    #[error("Outbound queue full (peer not keeping up)")]
36    OutboundQueueFull,
37    #[error("Peer disconnected")]
38    Disconnected,
39    #[error("Disconnect requested: {0}")]
40    DisconnectReceived(DisconnectReason),
41    #[error("Disconnect sent: {0}")]
42    DisconnectSent(DisconnectReason),
43    #[error("Not Found: {0}")]
44    NotFound(String),
45    #[error("Invalid peer id")]
46    InvalidPeerId,
47    #[error("Invalid recovery id")]
48    InvalidRecoveryId,
49    #[error("Invalid message length")]
50    InvalidMessageLength,
51    #[error("Request id not present: {0}")]
52    ExpectedRequestId(String),
53    #[error("Cannot handle message: {0}")]
54    MessageNotHandled(String),
55    #[error("Bad Request: {0}")]
56    BadRequest(String),
57    #[error(transparent)]
58    RLPDecodeError(#[from] RLPDecodeError),
59    #[error(transparent)]
60    RLPEncodeError(#[from] RLPEncodeError),
61    #[error(transparent)]
62    StoreError(#[from] StoreError),
63    #[error(transparent)]
64    #[cfg(feature = "l2")]
65    RollupStoreError(#[from] RollupStoreError),
66    #[error("Error in cryptographic library: {0}")]
67    CryptographyError(String),
68    #[error("Failed to broadcast msg: {0}")]
69    BroadcastError(String),
70    #[error("RecvError: {0}")]
71    RecvError(String),
72    #[error("Failed to send msg: {0}")]
73    SendMessage(String),
74    #[error("Error when inserting transaction in the mempool: {0}")]
75    MempoolError(#[from] MempoolError),
76    #[error("Error when adding a block to the blockchain: {0}")]
77    BlockchainError(#[from] ChainError),
78    #[error("Io Error: {0}")]
79    IoError(#[from] std::io::Error),
80    #[error("Failed to decode message due to invalid frame: {0}")]
81    InvalidMessageFrame(String),
82    #[error("Failed due to an internal error: {0}")]
83    InternalError(String),
84    #[error("Incompatible Protocol")]
85    IncompatibleProtocol,
86    #[error("Invalid block range")]
87    InvalidBlockRange,
88    #[error("An L2 functionality was used but it was not previously negotiated")]
89    L2CapabilityNotNegotiated,
90    #[error("Received invalid block range update")]
91    InvalidBlockRangeUpdate,
92    #[error(transparent)]
93    ActorError(#[from] ActorError),
94    #[error("Request timeouted")]
95    Timeout,
96    #[error("Unexpected response: Expected {0}, got {1}")]
97    UnexpectedResponse(String, String),
98}
99
100// tokio::sync::mpsc::error::SendError<Message> is too large to be part of the RLPxError enum directly
101// so we will instead save the error's display message
102impl From<tokio::sync::mpsc::error::SendError<Message>> for PeerConnectionError {
103    fn from(value: tokio::sync::mpsc::error::SendError<Message>) -> Self {
104        Self::SendMessage(value.to_string())
105    }
106}
107
108// Grouping all cryptographic related errors in a single CryptographicError variant
109// We can improve this to individual errors if required
110impl From<secp256k1::Error> for PeerConnectionError {
111    fn from(e: secp256k1::Error) -> Self {
112        PeerConnectionError::CryptographyError(e.to_string())
113    }
114}
115
116impl From<InvalidLength> for PeerConnectionError {
117    fn from(e: InvalidLength) -> Self {
118        PeerConnectionError::CryptographyError(e.to_string())
119    }
120}
121
122impl From<aes::cipher::StreamCipherError> for PeerConnectionError {
123    fn from(e: aes::cipher::StreamCipherError) -> Self {
124        PeerConnectionError::CryptographyError(e.to_string())
125    }
126}
127
128impl From<tokio::sync::broadcast::error::RecvError> for PeerConnectionError {
129    fn from(e: tokio::sync::broadcast::error::RecvError) -> Self {
130        PeerConnectionError::RecvError(e.to_string())
131    }
132}
133
134impl From<tokio::sync::oneshot::error::RecvError> for PeerConnectionError {
135    fn from(e: tokio::sync::oneshot::error::RecvError) -> Self {
136        PeerConnectionError::RecvError(e.to_string())
137    }
138}
139
140impl From<SnapError> for PeerConnectionError {
141    fn from(e: SnapError) -> Self {
142        match e {
143            SnapError::Store(e) => PeerConnectionError::StoreError(e),
144            SnapError::Protocol(e) => e,
145            SnapError::BadRequest(msg) => PeerConnectionError::BadRequest(msg),
146            other => PeerConnectionError::InternalError(other.to_string()),
147        }
148    }
149}