use thiserror::Error;
use tokio::{sync::mpsc, time::error::Elapsed};
use crate::{
connection_manager::PeerConnectionRequest,
multiplexing::YamuxControlError,
noise,
noise::NoiseError,
peer_manager::PeerManagerError,
peer_validator::PeerValidatorError,
protocol::{IdentityProtocolError, ProtocolError},
};
#[derive(Debug, Error, Clone)]
pub enum ConnectionManagerError {
#[error("Peer manager error: {0}")]
PeerManagerError(#[from] PeerManagerError),
#[error("Peer connection error: {0}")]
PeerConnectionError(String),
#[error("Failed to send request to ConnectionManagerActor. Channel closed.")]
SendToActorFailed,
#[error("Request was canceled before the response could be sent")]
ActorRequestCanceled,
#[error("Failed to connect on all addresses for peer")]
DialConnectFailedAllAddresses,
#[error("Failed to connect to peer within the maximum number of attempts")]
ConnectFailedMaximumAttemptsReached,
#[error("Yamux connection error: {0}")]
YamuxConnectionError(String),
#[error("Failed to perform yamux upgrade on socket: {0}")]
YamuxUpgradeFailure(String),
#[error("Failed to listen on {address}: {details}")]
ListenerError { address: String, details: String },
#[error("Transport error for {address}: {details}")]
TransportError { address: String, details: String },
#[error("Dial timeout dialing {address} after {timeout}")]
DialTimeout { address: String, timeout: String },
#[error(
"The peer authenticated to public key '{authenticated_pk}' which did not match the dialed peer's public key \
'{expected_pk}'"
)]
DialedPublicKeyMismatch {
authenticated_pk: String,
expected_pk: String,
},
#[error("The noise transport failed to provide a valid static public key for the peer")]
InvalidStaticPublicKey,
#[error("Noise snow error: {0}")]
NoiseSnowError(String),
#[error("Noise handshake error: {0}")]
NoiseHandshakeError(String),
#[error("Peer is banned, denying connection")]
PeerBanned,
#[error("Identity protocol failed: {0}")]
IdentityProtocolError(#[from] IdentityProtocolError),
#[error("The dial was cancelled")]
DialCancelled,
#[error("Invalid multiaddr")]
InvalidMultiaddr(String),
#[error("Failed to send wire format byte")]
WireFormatSendFailed,
#[error("Listener oneshot cancelled")]
ListenerOneshotCancelled,
#[error("Peer validation error: {0}")]
PeerValidationError(#[from] PeerValidatorError),
#[error("No contactable addresses for peer {0} left")]
NoContactableAddressesForPeer(String),
#[error("All peer addresses are excluded for peer {0}")]
AllPeerAddressesAreExcluded(String),
#[error("Yamux error: {0}")]
YamuxControlError(#[from] YamuxControlError),
}
impl From<yamux::ConnectionError> for ConnectionManagerError {
fn from(err: yamux::ConnectionError) -> Self {
ConnectionManagerError::YamuxConnectionError(err.to_string())
}
}
impl From<noise::NoiseError> for ConnectionManagerError {
fn from(err: noise::NoiseError) -> Self {
match err {
NoiseError::SnowError(e) => ConnectionManagerError::NoiseSnowError(e.to_string()),
NoiseError::HandshakeFailed(e) => ConnectionManagerError::NoiseHandshakeError(e.to_string()),
}
}
}
impl From<PeerConnectionError> for ConnectionManagerError {
fn from(err: PeerConnectionError) -> Self {
ConnectionManagerError::PeerConnectionError(err.to_string())
}
}
#[derive(Debug, Error)]
pub enum PeerConnectionError {
#[error("Yamux error: {0}")]
YamuxControlError(#[from] YamuxControlError),
#[error("Internal oneshot reply channel was unexpectedly cancelled")]
InternalReplyCancelled,
#[error("Failed to send internal request: {0}")]
InternalRequestSendFailed(#[from] mpsc::error::SendError<PeerConnectionRequest>),
#[error("Protocol error: {0}")]
ProtocolError(#[from] ProtocolError),
#[error("Protocol negotiation timeout")]
ProtocolNegotiationTimeout,
#[error("Timeout disconnecting peer")]
DisconnectTimeout,
}
impl From<Elapsed> for PeerConnectionError {
fn from(_: Elapsed) -> Self {
PeerConnectionError::ProtocolNegotiationTimeout
}
}