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    /// Ping started before the handshake completed.
67    #[error("started ping task before the handshake completed")]
68    PingBeforeHandshake,
69
70    /// Too many messages buffered before sending.
71    #[error("too many messages buffered before sending")]
72    SendBufferFull,
73
74    /// Disconnected error.
75    #[error("disconnected")]
76    Disconnected(DisconnectReason),
77
78    /// Unknown disconnect reason error.
79    #[error("unknown disconnect reason: {0}")]
80    UnknownDisconnectReason(#[from] UnknownDisconnectReason),
81}
82
83// === impl P2PStreamError ===
84
85impl P2PStreamError {
86    /// Returns the [`DisconnectReason`] if it is the `Disconnected` variant.
87    pub const fn as_disconnected(&self) -> Option<DisconnectReason> {
88        let reason = match self {
89            Self::HandshakeError(P2PHandshakeError::Disconnected(reason)) |
90            Self::Disconnected(reason) => reason,
91            _ => return None,
92        };
93
94        Some(*reason)
95    }
96}
97
98/// Errors when conducting a p2p handshake.
99#[derive(thiserror::Error, Debug, Clone, Eq, PartialEq)]
100pub enum P2PHandshakeError {
101    /// Hello message received/sent outside of handshake error.
102    #[error("hello message can only be recv/sent in handshake")]
103    HelloNotInHandshake,
104
105    /// Received a non-hello message when trying to handshake.
106    #[error("received non-hello message when trying to handshake")]
107    NonHelloMessageInHandshake,
108
109    /// No capabilities shared with the peer.
110    #[error("no capabilities shared with peer")]
111    NoSharedCapabilities,
112
113    /// No response received when sending out handshake.
114    #[error("no response received when sending out handshake")]
115    NoResponse,
116
117    /// Handshake timed out.
118    #[error("handshake timed out")]
119    Timeout,
120
121    /// Disconnected by peer with a specific reason.
122    #[error("disconnected by peer: {0}")]
123    Disconnected(DisconnectReason),
124
125    /// Error decoding a message during handshake.
126    #[error("error decoding a message during handshake: {0}")]
127    DecodeError(#[from] alloy_rlp::Error),
128}
129
130/// An error that can occur when interacting with a pinger.
131#[derive(Debug, thiserror::Error)]
132pub enum PingerError {
133    /// An unexpected pong was received while the pinger was in the `Ready` state.
134    #[error("pong received while ready")]
135    UnexpectedPong,
136}