use core::fmt;
use core::fmt::Display;
use core::fmt::Formatter;
use core::net::IpAddr;
use std::io;
use floresta_chain::BlockchainError;
use floresta_common::impl_error_from;
use floresta_compact_filters::IterableFilterStoreError;
use tokio::sync::mpsc::error::SendError;
use super::peer::PeerError;
use super::transport::TransportError;
use crate::node::NodeRequest;
#[derive(Debug)]
pub enum WireError {
Blockchain(BlockchainError),
ChannelSend(SendError<NodeRequest>),
PeerError(PeerError),
CoinbaseNotMatured,
PeerNotFound,
NoPeersAvailable,
PeerMisbehaving,
AnchorFileNotFound,
PeerAlreadyExists(IpAddr, u16),
PeerNotFoundAtAddress(IpAddr, u16),
Io(std::io::Error),
Serde(serde_json::Error),
NoUtreexoPeersAvailable,
NoPeerToSendRequest,
PeerTimeout,
CompactBlockFiltersError(IterableFilterStoreError),
PoisonedLock,
InvalidAddress(AddrParseError),
Transport(TransportError),
ResponseSendError,
NoAddressesAvailable,
BlockNotFound,
BlockProofNotFound,
LeafDataNotFound,
}
impl Display for WireError {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
WireError::Blockchain(err) => write!(f, "Blockchain error: {err:?}"),
WireError::ChannelSend(err) => write!(f, "Error while writing into channel: {err:?}"),
WireError::PeerError(err) => write!(f, "Peer error: {err:?}"),
WireError::CoinbaseNotMatured => write!(f, "Coinbase isn't mature yet"),
WireError::PeerNotFound => write!(f, "Peer not found in our current connections list"),
WireError::NoPeersAvailable => write!(f, "We don't have peers to send a given request"),
WireError::PeerMisbehaving => write!(f, "Our peer is misbehaving"),
WireError::AnchorFileNotFound => write!(
f,
"Failed to init Utreexo peers: anchors.json does not exist yet"
),
WireError::PeerAlreadyExists(ip, port) => write!(f, "Peer {ip}:{port} already exists"),
WireError::PeerNotFoundAtAddress(ip, port) => write!(f, "Peer {ip}:{port} not found"),
WireError::Io(err) => write!(f, "Generic IO error: {err:?}"),
WireError::Serde(err) => write!(f, "Serde error: {err:?}"),
WireError::NoUtreexoPeersAvailable => write!(
f,
"Failed to save Utreexo peers: no peers to save to anchors.json"
),
WireError::NoPeerToSendRequest => {
write!(f, "We couldn't find a peer to send the request")
}
WireError::PeerTimeout => write!(f, "Peer timed out"),
WireError::CompactBlockFiltersError(err) => {
write!(f, "Compact block filters error: {err:?}")
}
WireError::PoisonedLock => write!(f, "Poisoned lock"),
WireError::InvalidAddress(err) => {
write!(f, "We couldn't parse the provided address due to: {err:?}")
}
WireError::Transport(err) => write!(f, "Transport error: {err:?}"),
WireError::ResponseSendError => write!(f, "Can't send back response for user request"),
WireError::NoAddressesAvailable => write!(f, "No addresses available to connect to"),
WireError::BlockNotFound => write!(f, "We tried to work on a block we don't have"),
WireError::BlockProofNotFound => write!(
f,
"We tried to work on a block that we don't have a proof for yet"
),
WireError::LeafDataNotFound => write!(f, "Couldn't find the leaf data for a block"),
}
}
}
impl_error_from!(WireError, PeerError, PeerError);
impl_error_from!(WireError, BlockchainError, Blockchain);
impl_error_from!(
WireError,
IterableFilterStoreError,
CompactBlockFiltersError
);
impl_error_from!(WireError, AddrParseError, InvalidAddress);
impl_error_from!(WireError, SendError<NodeRequest>, ChannelSend);
impl_error_from!(WireError, serde_json::Error, Serde);
impl_error_from!(WireError, io::Error, Io);
impl From<tokio::sync::oneshot::error::RecvError> for WireError {
fn from(_: tokio::sync::oneshot::error::RecvError) -> Self {
WireError::ResponseSendError
}
}
impl From<TransportError> for WireError {
fn from(e: TransportError) -> Self {
match e {
TransportError::Io(io) => WireError::Io(io),
other => WireError::Transport(other),
}
}
}
#[derive(Debug, Clone)]
pub enum AddrParseError {
InvalidIpv6,
InvalidIpv4,
InvalidHostname,
InvalidPort,
Inconclusive,
}
impl Display for AddrParseError {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self {
AddrParseError::InvalidIpv6 => write!(f, "Invalid ipv6"),
AddrParseError::InvalidIpv4 => write!(f, "Invalid ipv4"),
AddrParseError::InvalidHostname => write!(f, "Invalid hostname"),
AddrParseError::InvalidPort => write!(f, "Invalid port"),
AddrParseError::Inconclusive => write!(f, "Inconclusive"),
}
}
}