use std::{error, io, net::SocketAddr, result};
use datasize::DataSize;
use openssl::{error::ErrorStack, ssl};
use serde::Serialize;
use thiserror::Error;
use casper_types::{crypto, Digest, ProtocolVersion};
use crate::{
tls::{LoadCertError, ValidationError},
utils::ResolveAddressError,
};
pub(super) type Result<T> = result::Result<T, Error>;
#[derive(Debug, Error, Serialize)]
pub enum Error {
#[error("could not resolve at least one known host (or none provided)")]
EmptyKnownHosts,
#[error("failed to create listener on {1}")]
ListenerCreation(
#[serde(skip_serializing)]
#[source]
io::Error,
SocketAddr,
),
#[error("failed to get listener addr")]
ListenerAddr(
#[serde(skip_serializing)]
#[source]
io::Error,
),
#[error("failed to set listener to non-blocking")]
ListenerSetNonBlocking(
#[serde(skip_serializing)]
#[source]
io::Error,
),
#[error("failed to convert listener to tokio")]
ListenerConversion(
#[serde(skip_serializing)]
#[source]
io::Error,
),
#[error("failed to resolve network address")]
ResolveAddr(
#[serde(skip_serializing)]
#[source]
ResolveAddressError,
),
#[error(transparent)]
Metrics(
#[serde(skip_serializing)]
#[from]
prometheus::Error,
),
#[error("failed to load a certificate: {0}")]
LoadCertificate(
#[serde(skip_serializing)]
#[from]
LoadCertError,
),
}
impl DataSize for Error {
const IS_DYNAMIC: bool = false;
const STATIC_HEAP_SIZE: usize = 0;
fn estimate_heap_size(&self) -> usize {
0
}
}
impl DataSize for ConnectionError {
const IS_DYNAMIC: bool = false;
const STATIC_HEAP_SIZE: usize = 0;
fn estimate_heap_size(&self) -> usize {
0
}
}
#[derive(Debug, Error, Serialize)]
pub enum ConnectionError {
#[error("failed to create TLS acceptor/connector")]
TlsInitialization(
#[serde(skip_serializing)]
#[source]
ErrorStack,
),
#[error("TCP connection failed")]
TcpConnection(
#[serde(skip_serializing)]
#[source]
io::Error,
),
#[error("Could not set TCP_NODELAY on outgoing connection")]
TcpNoDelay(
#[serde(skip_serializing)]
#[source]
io::Error,
),
#[error("TLS handshake error")]
TlsHandshake(
#[serde(skip_serializing)]
#[source]
ssl::Error,
),
#[error("no client certificate presented")]
NoPeerCertificate,
#[error("TLS validation error of peer certificate")]
PeerCertificateInvalid(#[source] ValidationError),
#[error("handshake send failed")]
HandshakeSend(
#[serde(skip_serializing)]
#[source]
IoError<io::Error>,
),
#[error("handshake receive failed")]
HandshakeRecv(
#[serde(skip_serializing)]
#[source]
IoError<io::Error>,
),
#[error("peer is on different network: {0}")]
WrongNetwork(String),
#[error("peer is running incompatible version: {0}")]
IncompatibleVersion(ProtocolVersion),
#[error("peer is using a different chainspec, hash: {0}")]
WrongChainspecHash(Digest),
#[error("peer did not include chainspec hash in the handshake when it was required")]
MissingChainspecHash,
#[error("peer did not send handshake")]
DidNotSendHandshake,
#[error("could not encode our handshake")]
CouldNotEncodeOurHandshake(
#[serde(skip_serializing)]
#[source]
io::Error,
),
#[error("handshake sender crashed")]
HandshakeSenderCrashed(
#[serde(skip_serializing)]
#[source]
tokio::task::JoinError,
),
#[error("could not decode remote handshake message")]
InvalidRemoteHandshakeMessage(
#[serde(skip_serializing)]
#[source]
io::Error,
),
#[error("invalid consensus certificate")]
InvalidConsensusCertificate(
#[serde(skip_serializing)]
#[source]
crypto::Error,
),
#[error("handshake sink/stream could not be reunited")]
FailedToReuniteHandshakeSinkAndStream,
#[error("handshake not allowed (Isolated mode)")]
HandshakeNotAllowed,
}
#[derive(Debug, Error)]
pub enum IoError<E>
where
E: error::Error + 'static,
{
#[error("io timeout")]
Timeout,
#[error(transparent)]
Error(#[from] E),
#[error("closed unexpectedly")]
UnexpectedEof,
}