use std::fmt;
use multiaddr::Multiaddr;
use tari_common_sqlite::error::StorageError;
use tari_utilities::hex::{Hex, HexError};
use thiserror::Error;
use tokio::task::JoinError;
use crate::peer_manager::NodeId;
#[derive(Debug, Error, Clone)]
pub enum PeerManagerError {
#[error("The requested peer does not exist: {0}")]
PeerNotFound(DisplayVec),
#[error("DB Data inconsistency: {0}")]
DataInconsistency(String),
#[error("The peer has been banned")]
BannedPeer,
#[error("A problem has been encountered with the sql database: {0}")]
StorageError(String),
#[error("An error occurred while migrating the database: {0}")]
MigrationError(String),
#[error("Identity signature is invalid")]
InvalidIdentitySignature,
#[error("Identity signature missing")]
MissingIdentitySignature,
#[error("Invalid peer address: {0}")]
MultiaddrError(String),
#[error("Unable to parse any of the network addresses offered by the connecting peer")]
PeerIdentityNoValidAddresses,
#[error("Invalid peer feature bits '{bits:#x}'")]
InvalidPeerFeatures { bits: u32 },
#[error("Address {address} not found for peer {node_id}")]
AddressNotFoundError { address: Multiaddr, node_id: NodeId },
#[error("Protocol error: {0}")]
ProtocolError(String),
#[error("Invalid version string")]
InvalidVersionString,
#[error("Peer version {peer_version} to older than the minimum required version {min_version}")]
PeerVersionTooOld { min_version: String, peer_version: String },
#[error("Hex conversion error: `{0}`")]
HexError(String),
#[error("Tokio task join error: `{0}`")]
JoinError(String),
#[error("Process error: `{0}`")]
ProcessError(String),
}
impl From<JoinError> for PeerManagerError {
fn from(err: JoinError) -> Self {
PeerManagerError::JoinError(err.to_string())
}
}
impl From<StorageError> for PeerManagerError {
fn from(err: StorageError) -> Self {
PeerManagerError::StorageError(err.to_string())
}
}
impl From<HexError> for PeerManagerError {
fn from(value: HexError) -> Self {
PeerManagerError::HexError(value.to_string())
}
}
impl From<std::io::Error> for PeerManagerError {
fn from(value: std::io::Error) -> Self {
PeerManagerError::StorageError(value.to_string())
}
}
#[derive(Debug, Error, Clone)]
pub struct DisplayVec(Vec<NodeId>);
impl fmt::Display for DisplayVec {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"[{}]",
self.0.iter().map(|v| v.to_hex()).collect::<Vec<_>>().join(", ")
)
}
}
impl PeerManagerError {
pub fn peer_not_found(peer: &NodeId) -> Self {
PeerManagerError::PeerNotFound(DisplayVec(vec![peer.clone()]))
}
pub fn peers_not_found<T>(peers: T) -> Self
where T: AsRef<[NodeId]> {
PeerManagerError::PeerNotFound(DisplayVec(peers.as_ref().to_vec()))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_peer_not_found() {
let peers = [
NodeId::from_hex("abb1556d806c2ff042f433ca0a").unwrap(),
NodeId::from_hex("ba9ab662a6d974c5a607562326").unwrap(),
NodeId::from_hex("97676095b1901327bdc36e8cb6").unwrap(),
];
let error = PeerManagerError::peers_not_found(&peers);
assert_eq!(
error.to_string(),
"The requested peer does not exist: [abb1556d806c2ff042f433ca0a, ba9ab662a6d974c5a607562326, \
97676095b1901327bdc36e8cb6]"
);
let error = PeerManagerError::peer_not_found(&peers[0]);
assert_eq!(
error.to_string(),
"The requested peer does not exist: [abb1556d806c2ff042f433ca0a]"
);
}
}