reth_eth_wire/errors/
p2p.rs

1//! Error handling for [`P2PStream`](crate::P2PStream).
2
3use std::io;
4
5use reth_eth_wire_types::{DisconnectReason, UnknownDisconnectReason};
6use reth_primitives_traits::GotExpected;
7
8use crate::{capability::SharedCapabilityError, ProtocolVersion};
9
10/// Errors when sending/receiving p2p messages. These should result in kicking the peer.
11#[derive(thiserror::Error, Debug)]
12pub enum P2PStreamError {
13    /// I/O error.
14    #[error(transparent)]
15    Io(#[from] io::Error),
16
17    /// RLP encoding/decoding error.
18    #[error(transparent)]
19    Rlp(#[from] alloy_rlp::Error),
20
21    /// Error in compression/decompression using Snappy.
22    #[error(transparent)]
23    Snap(#[from] snap::Error),
24
25    /// Error during the P2P handshake.
26    #[error(transparent)]
27    HandshakeError(#[from] P2PHandshakeError),
28
29    /// Message size exceeds maximum length error.
30    #[error("message size ({message_size}) exceeds max length ({max_size})")]
31    MessageTooBig {
32        /// The actual size of the message received.
33        message_size: usize,
34        /// The maximum allowed size for the message.
35        max_size: usize,
36    },
37
38    /// Unknown reserved P2P message ID error.
39    #[error("unknown reserved p2p message id: {0}")]
40    UnknownReservedMessageId(u8),
41
42    /// Empty protocol message received error.
43    #[error("empty protocol message received")]
44    EmptyProtocolMessage,
45
46    /// Error related to the Pinger.
47    #[error(transparent)]
48    PingerError(#[from] PingerError),
49
50    /// Ping timeout error.
51    #[error("ping timed out with")]
52    PingTimeout,
53
54    /// Error parsing shared capabilities.
55    #[error(transparent)]
56    ParseSharedCapability(#[from] SharedCapabilityError),
57
58    /// Capability not supported on the stream to this peer.
59    #[error("capability not supported on stream to this peer")]
60    CapabilityNotShared,
61
62    /// Mismatched protocol version error.
63    #[error("mismatched protocol version in Hello message: {0}")]
64    MismatchedProtocolVersion(GotExpected<ProtocolVersion>),
65
66    /// Too many messages buffered before sending.
67    #[error("too many messages buffered before sending")]
68    SendBufferFull,
69
70    /// Disconnected error.
71    #[error("disconnected")]
72    Disconnected(DisconnectReason),
73
74    /// Unknown disconnect reason error.
75    #[error("unknown disconnect reason: {0}")]
76    UnknownDisconnectReason(#[from] UnknownDisconnectReason),
77}
78
79// === impl P2PStreamError ===
80
81impl P2PStreamError {
82    /// Returns the [`DisconnectReason`] if it is the `Disconnected` variant.
83    pub const fn as_disconnected(&self) -> Option<DisconnectReason> {
84        let reason = match self {
85            Self::HandshakeError(P2PHandshakeError::Disconnected(reason)) |
86            Self::Disconnected(reason) => reason,
87            _ => return None,
88        };
89
90        Some(*reason)
91    }
92}
93
94/// Errors when conducting a p2p handshake.
95#[derive(thiserror::Error, Debug, Clone, Eq, PartialEq)]
96pub enum P2PHandshakeError {
97    /// Hello message received/sent outside of handshake error.
98    #[error("hello message can only be recv/sent in handshake")]
99    HelloNotInHandshake,
100
101    /// Received a non-hello message when trying to handshake.
102    #[error("received non-hello message when trying to handshake")]
103    NonHelloMessageInHandshake,
104
105    /// No capabilities shared with the peer.
106    #[error("no capabilities shared with peer")]
107    NoSharedCapabilities,
108
109    /// No response received when sending out handshake.
110    #[error("no response received when sending out handshake")]
111    NoResponse,
112
113    /// Handshake timed out.
114    #[error("handshake timed out")]
115    Timeout,
116
117    /// Disconnected by peer with a specific reason.
118    #[error("disconnected by peer: {0}")]
119    Disconnected(DisconnectReason),
120
121    /// Error decoding a message during handshake.
122    #[error("error decoding a message during handshake: {0}")]
123    DecodeError(#[from] alloy_rlp::Error),
124}
125
126/// An error that can occur when interacting with a pinger.
127#[derive(Debug, thiserror::Error)]
128pub enum PingerError {
129    /// An unexpected pong was received while the pinger was in the `Ready` state.
130    #[error("pong received while ready")]
131    UnexpectedPong,
132}