From 29cd5ab3173c0697184d2b745f6ef8212b2144a0 Mon Sep 17 00:00:00 2001 From: Stanimal Date: Thu, 4 Jun 2020 14:02:44 +0200 Subject: [PATCH] Migrate Comms/DHT to thiserror Comms/DHT are using thiserror. derive_error dependency removed. --- base_layer/wallet_ffi/src/error.rs | 9 +-- comms/Cargo.toml | 2 +- comms/dht/Cargo.toml | 2 +- comms/dht/src/actor.rs | 38 ++++++---- comms/dht/src/connectivity/mod.rs | 13 ++-- comms/dht/src/dht.rs | 12 +-- comms/dht/src/discovery/error.rs | 27 ++++--- comms/dht/src/envelope.rs | 21 +++-- comms/dht/src/inbound/decryption.rs | 16 ++-- comms/dht/src/inbound/error.rs | 25 +++--- comms/dht/src/outbound/error.rs | 31 ++++---- comms/dht/src/storage/error.rs | 18 +++-- comms/dht/src/store_forward/error.rs | 69 +++++++++-------- .../dht/src/store_forward/saf_handler/task.rs | 16 ++-- comms/examples/tor.rs | 25 +++--- comms/src/builder/error.rs | 24 +++--- comms/src/connection_manager/error.rs | 66 ++++++++-------- comms/src/connectivity/error.rs | 16 ++-- comms/src/message/error.rs | 34 +-------- comms/src/noise/error.rs | 16 +--- comms/src/peer_manager/error.rs | 10 +-- comms/src/peer_manager/node_id.rs | 76 +++++++++---------- comms/src/peer_manager/node_identity.rs | 11 +-- comms/src/pipeline/builder.rs | 6 +- comms/src/protocol/error.rs | 32 +++----- comms/src/protocol/identity.rs | 14 ++-- comms/src/protocol/messaging/error.rs | 31 ++++---- comms/src/protocol/messaging/protocol.rs | 8 +- comms/src/protocol/protocols.rs | 5 +- comms/src/socks/error.rs | 46 ++++++----- comms/src/test_utils/factories/mod.rs | 5 +- comms/src/tor/control_client/error.rs | 27 +++---- comms/src/tor/control_client/event.rs | 4 +- comms/src/tor/hidden_service/builder.rs | 9 ++- comms/src/tor/hidden_service/controller.rs | 15 ++-- comms/src/utils/signature.rs | 18 ++--- 36 files changed, 389 insertions(+), 408 deletions(-) diff --git a/base_layer/wallet_ffi/src/error.rs b/base_layer/wallet_ffi/src/error.rs index 2291b07c1d..80d6686d20 100644 --- a/base_layer/wallet_ffi/src/error.rs +++ b/base_layer/wallet_ffi/src/error.rs @@ -285,15 +285,12 @@ impl From for LibWalletError { code: 701, message: format!("{:?}", n), }, - NodeIdentityError::NodeIdError(NodeIdError::OutOfBounds) => Self { - code: 702, - message: format!("{:?}", n), - }, - NodeIdentityError::PoisonedAccess => Self { + // 702 NodeIdError::OutOfBounds no longer occurs + NodeIdentityError::AddressLockPoisoned => Self { code: 703, message: format!("{:?}", n), }, - NodeIdentityError::NodeIdError(NodeIdError::DigestError) => Self { + NodeIdentityError::NodeIdError(NodeIdError::InvalidDigestOutputSize) => Self { code: 704, message: format!("{:?}", n), }, diff --git a/comms/Cargo.toml b/comms/Cargo.toml index a043ee35b2..cc390b2e9e 100644 --- a/comms/Cargo.toml +++ b/comms/Cargo.toml @@ -21,7 +21,6 @@ chrono = { version = "0.4.6", features = ["serde"] } cidr = "0.1.0" clear_on_drop = "=0.2.3" data-encoding = "2.2.0" -derive-error = "0.0.4" digest = "0.8.0" futures = { version = "^0.3", features = ["async-await"]} lazy_static = "1.3.0" @@ -35,6 +34,7 @@ rand = "0.7.2" serde = "1.0.90" serde_derive = "1.0.90" snow = {version="=0.6.2", features=["default-resolver"]} +thiserror = "1.0.19" tokio = {version="~0.2.19", features=["blocking", "time", "tcp", "dns", "sync", "stream", "signal"]} tokio-util = {version="0.2.0", features=["codec"]} tower= "0.3.1" diff --git a/comms/dht/Cargo.toml b/comms/dht/Cargo.toml index b2c87a2ddf..f8b9d5fb3a 100644 --- a/comms/dht/Cargo.toml +++ b/comms/dht/Cargo.toml @@ -22,7 +22,6 @@ tari_storage = { version = "^0.1", path = "../../infrastructure/storage"} bitflags = "1.2.0" bytes = "0.4.12" chrono = "0.4.9" -derive-error = "0.0.4" diesel = {version="1.4", features = ["sqlite", "serde_json", "chrono", "numeric"]} diesel_migrations = "1.4" digest = "0.8.1" @@ -40,6 +39,7 @@ ttl_cache = "0.5.1" # tower-filter dependencies pin-project = "0.4" +thiserror = "1.0.19" [dev-dependencies] tari_test_utils = { version = "^0.0", path = "../../infrastructure/test_utils"} diff --git a/comms/dht/src/actor.rs b/comms/dht/src/actor.rs index aa48227157..99897bfd80 100644 --- a/comms/dht/src/actor.rs +++ b/comms/dht/src/actor.rs @@ -36,7 +36,6 @@ use crate::{ DhtConfig, }; use chrono::{DateTime, Utc}; -use derive_error::Error; use futures::{ channel::{mpsc, mpsc::SendError, oneshot}, future, @@ -54,6 +53,7 @@ use tari_comms::{ }; use tari_shutdown::ShutdownSignal; use tari_utilities::message_format::{MessageFormat, MessageFormatError}; +use thiserror::Error; use tokio::task; use ttl_cache::TtlCache; @@ -61,25 +61,29 @@ const LOG_TARGET: &str = "comms::dht::actor"; #[derive(Debug, Error)] pub enum DhtActorError { - /// MPSC channel is disconnected + #[error("MPSC channel is disconnected")] ChannelDisconnected, - /// MPSC sender was unable to send because the channel buffer is full + #[error("MPSC sender was unable to send because the channel buffer is full")] SendBufferFull, - /// Reply sender canceled the request + #[error("Reply sender canceled the request")] ReplyCanceled, - PeerManagerError(PeerManagerError), - #[error(msg_embedded, no_from, non_std)] - SendFailed(String), - DiscoveryError(DhtDiscoveryError), - BlockingJoinError(tokio::task::JoinError), - StorageError(StorageError), - #[error(no_from)] + #[error("PeerManagerError: {0}")] + PeerManagerError(#[from] PeerManagerError), + #[error("Failed to broadcast join message: {0}")] + FailedToBroadcastJoinMessage(String), + #[error("DiscoveryError: {0}")] + DiscoveryError(#[from] DhtDiscoveryError), + #[error("StorageError: {0}")] + StorageError(#[from] StorageError), + #[error("StoredValueFailedToDeserialize: {0}")] StoredValueFailedToDeserialize(MessageFormatError), - #[error(no_from)] + #[error("FailedToSerializeValue: {0}")] FailedToSerializeValue(MessageFormatError), - ConnectionManagerError(ConnectionManagerError), - ConnectivityError(ConnectivityError), - /// Connectivity event stream closed + #[error("ConnectionManagerError: {0}")] + ConnectionManagerError(#[from] ConnectionManagerError), + #[error("ConnectivityError: {0}")] + ConnectivityError(#[from] ConnectivityError), + #[error("Connectivity event stream closed")] ConnectivityEventStreamClosed, } @@ -350,7 +354,9 @@ impl DhtActor { message, ) .await - .map_err(|err| DhtActorError::SendFailed(format!("Failed to send join message: {}", err)))?; + .map_err(|err| { + DhtActorError::FailedToBroadcastJoinMessage(format!("Failed to send join message: {}", err)) + })?; Ok(()) } diff --git a/comms/dht/src/connectivity/mod.rs b/comms/dht/src/connectivity/mod.rs index 37bcc36875..e63006ac21 100644 --- a/comms/dht/src/connectivity/mod.rs +++ b/comms/dht/src/connectivity/mod.rs @@ -24,7 +24,6 @@ mod test; use crate::{DhtActorError, DhtConfig, DhtRequester}; -use derive_error::Error; use futures::StreamExt; use log::*; use std::{sync::Arc, time::Instant}; @@ -36,17 +35,19 @@ use tari_comms::{ PeerManager, }; use tari_shutdown::ShutdownSignal; +use thiserror::Error; use tokio::{task, task::JoinHandle, time}; const LOG_TARGET: &str = "comms::dht::connectivity"; #[derive(Debug, Error)] pub enum DhtConnectivityError { - ConnectivityError(ConnectivityError), - PeerManagerError(PeerManagerError), - /// Failed to send network Join message - #[error(no_from)] - SendJoinFailed(DhtActorError), + #[error("ConnectivityError: {0}")] + ConnectivityError(#[from] ConnectivityError), + #[error("PeerManagerError: {0}")] + PeerManagerError(#[from] PeerManagerError), + #[error("Failed to send network Join message: {0}")] + SendJoinFailed(#[from] DhtActorError), } /// # DHT Connectivity Actor diff --git a/comms/dht/src/dht.rs b/comms/dht/src/dht.rs index 94916031a5..00ad44f26f 100644 --- a/comms/dht/src/dht.rs +++ b/comms/dht/src/dht.rs @@ -39,7 +39,6 @@ use crate::{ DhtActorError, DhtConfig, }; -use derive_error::Error; use futures::{channel::mpsc, future, Future}; use log::*; use std::sync::Arc; @@ -50,6 +49,7 @@ use tari_comms::{ pipeline::PipelineError, }; use tari_shutdown::ShutdownSignal; +use thiserror::Error; use tower::{layer::Layer, Service, ServiceBuilder}; const LOG_TARGET: &str = "comms::dht"; @@ -60,10 +60,12 @@ const DHT_SAF_SERVICE_CHANNEL_SIZE: usize = 100; #[derive(Debug, Error)] pub enum DhtInitializationError { - /// Database initialization failed - DatabaseMigrationFailed(StorageError), - StoreAndForwardInitializationError(StoreAndForwardError), - DhtActorInitializationError(DhtActorError), + #[error("Database initialization failed: {0}")] + DatabaseMigrationFailed(#[from] StorageError), + #[error("StoreAndForwardInitializationError: {0}")] + StoreAndForwardInitializationError(#[from] StoreAndForwardError), + #[error("DhtActorInitializationError: {0}")] + DhtActorInitializationError(#[from] DhtActorError), } /// Responsible for starting the DHT actor, building the DHT middleware stack and as a factory diff --git a/comms/dht/src/discovery/error.rs b/comms/dht/src/discovery/error.rs index 1f3d3e8fdd..4689324976 100644 --- a/comms/dht/src/discovery/error.rs +++ b/comms/dht/src/discovery/error.rs @@ -21,31 +21,34 @@ // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. use crate::outbound::DhtOutboundError; -use derive_error::Error; use futures::channel::mpsc::SendError; use tari_comms::{connection_manager::ConnectionManagerError, peer_manager::PeerManagerError}; +use thiserror::Error; #[derive(Debug, Error)] pub enum DhtDiscoveryError { - /// The reply channel was canceled + #[error("The reply channel was canceled")] ReplyCanceled, - DhtOutboundError(DhtOutboundError), - /// Received public key in peer discovery response which does not match the requested public key + #[error("DhtOutboundError: {0}")] + DhtOutboundError(#[from] DhtOutboundError), + #[error("Received public key in peer discovery response which does not match the requested public key")] DiscoveredPeerMismatch, - /// Received an invalid `NodeId` + #[error("Received an invalid `NodeId`")] InvalidNodeId, - /// MPSC channel is disconnected + #[error("MPSC channel is disconnected")] ChannelDisconnected, - /// MPSC sender was unable to send because the channel buffer is full + #[error("MPSC sender was unable to send because the channel buffer is full")] SendBufferFull, - /// The discovery request timed out + #[error("The discovery request timed out")] DiscoveryTimeout, - /// Failed to send discovery message + #[error("Failed to send discovery message")] DiscoverySendFailed, - PeerManagerError(PeerManagerError), - #[error(msg_embedded, non_std, no_from)] + #[error("PeerManagerError: {0}")] + PeerManagerError(#[from] PeerManagerError), + #[error("InvalidPeerMultiaddr: {0}")] InvalidPeerMultiaddr(String), - ConnectionManagerError(ConnectionManagerError), + #[error("ConnectionManagerError: {0}")] + ConnectionManagerError(#[from] ConnectionManagerError), } impl DhtDiscoveryError { diff --git a/comms/dht/src/envelope.rs b/comms/dht/src/envelope.rs index 604c1ad2b8..926f72dfcf 100644 --- a/comms/dht/src/envelope.rs +++ b/comms/dht/src/envelope.rs @@ -21,36 +21,35 @@ // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. use bitflags::bitflags; -use derive_error::Error; +use bytes::Bytes; use serde::{Deserialize, Serialize}; use std::{ convert::{TryFrom, TryInto}, fmt, fmt::Display, }; -use tari_comms::{peer_manager::NodeId, types::CommsPublicKey}; +use tari_comms::{message::MessageTag, peer_manager::NodeId, types::CommsPublicKey}; use tari_utilities::{ByteArray, ByteArrayError}; +use thiserror::Error; // Re-export applicable protos pub use crate::proto::envelope::{dht_header::Destination, DhtEnvelope, DhtHeader, DhtMessageType, Network}; -use bytes::Bytes; -use tari_comms::message::MessageTag; #[derive(Debug, Error)] pub enum DhtMessageError { - /// Invalid node destination + #[error("Invalid node destination")] InvalidDestination, - /// Invalid origin public key + #[error("Invalid origin public key")] InvalidOrigin, - /// Invalid or unrecognised DHT message type + #[error("Invalid or unrecognised DHT message type")] InvalidMessageType, - /// Invalid or unrecognised network type + #[error("Invalid or unrecognised network type")] InvalidNetwork, - /// Invalid or unrecognised DHT message flags + #[error("Invalid or unrecognised DHT message flags")] InvalidMessageFlags, - /// Invalid ephemeral public key + #[error("Invalid ephemeral public key")] InvalidEphemeralPublicKey, - /// Header was omitted from the message + #[error("Header was omitted from the message")] HeaderOmitted, } diff --git a/comms/dht/src/inbound/decryption.rs b/comms/dht/src/inbound/decryption.rs index a58da35d29..4e8d7f6f27 100644 --- a/comms/dht/src/inbound/decryption.rs +++ b/comms/dht/src/inbound/decryption.rs @@ -26,7 +26,6 @@ use crate::{ inbound::message::{DecryptedDhtMessage, DhtInboundMessage}, proto::envelope::OriginMac, }; -use derive_error::Error; use futures::{task::Context, Future}; use log::*; use prost::Message; @@ -39,23 +38,24 @@ use tari_comms::{ utils::signature, }; use tari_utilities::ByteArray; +use thiserror::Error; use tower::{layer::Layer, Service, ServiceExt}; const LOG_TARGET: &str = "comms::middleware::decryption"; #[derive(Error, Debug)] enum DecryptionError { - /// Failed to validate origin MAC signature + #[error("Failed to validate origin MAC signature")] OriginMacInvalidSignature, - /// Origin MAC contained an invalid public key + #[error("Origin MAC contained an invalid public key")] OriginMacInvalidPublicKey, - /// Origin MAC not provided for encrypted message + #[error("Origin MAC not provided for encrypted message")] OriginMacNotProvided, - /// Failed to decrypt origin MAC + #[error("Failed to decrypt origin MAC")] OriginMacDecryptedFailed, - /// Failed to decode clear-text origin MAC + #[error("Failed to decode clear-text origin MAC")] OriginMacClearTextDecodeFailed, - /// Failed to decrypt message body + #[error("Failed to decrypt message body")] MessageBodyDecryptionFailed, } @@ -213,7 +213,7 @@ where S: Service body: &[u8], ) -> Result<(), DecryptionError> { - if signature::verify(public_key, signature, body).unwrap_or(false) { + if signature::verify(public_key, signature, body) { Ok(()) } else { Err(DecryptionError::OriginMacInvalidSignature) diff --git a/comms/dht/src/inbound/error.rs b/comms/dht/src/inbound/error.rs index d383728263..3cf7a26bd4 100644 --- a/comms/dht/src/inbound/error.rs +++ b/comms/dht/src/inbound/error.rs @@ -21,24 +21,25 @@ // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. use crate::{discovery::DhtDiscoveryError, outbound::DhtOutboundError}; -use derive_error::Error; -use prost::DecodeError; use tari_comms::{message::MessageError, peer_manager::PeerManagerError}; +use thiserror::Error; #[derive(Debug, Error)] pub enum DhtInboundError { - MessageError(MessageError), - PeerManagerError(PeerManagerError), - DhtOutboundError(DhtOutboundError), - /// Failed to decode message - DecodeError(DecodeError), - /// Message body invalid + #[error("MessageError: {0}")] + MessageError(#[from] MessageError), + #[error("PeerManagerError: {0}")] + PeerManagerError(#[from] PeerManagerError), + #[error("DhtOutboundError: {0}")] + DhtOutboundError(#[from] DhtOutboundError), + #[error("Message body invalid")] InvalidMessageBody, - /// Node ID is invalid + #[error("Node ID is invalid")] InvalidNodeId, - /// All given addresses were invalid + #[error("All given addresses were invalid")] InvalidAddresses, - DhtDiscoveryError(DhtDiscoveryError), - #[error(msg_embedded, no_from, non_std)] + #[error("DhtDiscoveryError: {0}")] + DhtDiscoveryError(#[from] DhtDiscoveryError), + #[error("OriginRequired: {0}")] OriginRequired(String), } diff --git a/comms/dht/src/outbound/error.rs b/comms/dht/src/outbound/error.rs index 514c6f4da0..1e4bbf1fa8 100644 --- a/comms/dht/src/outbound/error.rs +++ b/comms/dht/src/outbound/error.rs @@ -20,33 +20,38 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -use derive_error::Error; use futures::channel::mpsc::SendError; use tari_comms::message::MessageError; use tari_crypto::{ signatures::SchnorrSignatureError, tari_utilities::{ciphers::cipher::CipherError, message_format::MessageFormatError}, }; +use thiserror::Error; #[derive(Debug, Error)] pub enum DhtOutboundError { - SendError(SendError), - MessageSerializationError(MessageError), - MessageFormatError(MessageFormatError), - SignatureError(SchnorrSignatureError), - CipherError(CipherError), - /// Requester reply channel closed before response was received + #[error("SendError: {0}")] + SendError(#[from] SendError), + #[error("MessageSerializationError: {0}")] + MessageSerializationError(#[from] MessageError), + #[error("MessageFormatError: {0}")] + MessageFormatError(#[from] MessageFormatError), + #[error("SignatureError: {0}")] + SignatureError(#[from] SchnorrSignatureError), + #[error("CipherError: {0}")] + CipherError(#[from] CipherError), + #[error("Requester reply channel closed before response was received")] RequesterReplyChannelClosed, - /// Peer selection failed + #[error("Peer selection failed")] PeerSelectionFailed, - /// Failed to send broadcast message + #[error("Failed to send broadcast message")] BroadcastFailed, - /// Reply channel cancelled + #[error("Reply channel cancelled")] ReplyChannelCanceled, - /// Attempted to send a message to ourselves + #[error("Attempted to send a message to ourselves")] SendToOurselves, - /// Discovery process failed + #[error("Discovery process failed")] DiscoveryFailed, - /// Failed to insert message hash + #[error("Failed to insert message hash")] FailedToInsertMessageHash, } diff --git a/comms/dht/src/storage/error.rs b/comms/dht/src/storage/error.rs index de94d7557c..f8a6dafd97 100644 --- a/comms/dht/src/storage/error.rs +++ b/comms/dht/src/storage/error.rs @@ -20,18 +20,22 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -use derive_error::Error; use tari_utilities::message_format::MessageFormatError; +use thiserror::Error; use tokio::task; #[derive(Debug, Error)] pub enum StorageError { - /// Database path contained non-UTF8 characters that are not supported by the host OS + #[error("Database path contained non-UTF8 characters that are not supported by the host OS")] InvalidUnicodePath, - JoinError(task::JoinError), - ConnectionError(diesel::ConnectionError), - #[error(msg_embedded, no_from, non_std)] + #[error("ConnectionError: {0}")] + ConnectionError(#[from] diesel::ConnectionError), + #[error("Error when joining to tokio task : {0}")] + JoinError(#[from] task::JoinError), + #[error("DatabaseMigrationFailed: {0}")] DatabaseMigrationFailed(String), - ResultError(diesel::result::Error), - MessageFormatError(MessageFormatError), + #[error("ResultError: {0}")] + ResultError(#[from] diesel::result::Error), + #[error("MessageFormatError: {0}")] + MessageFormatError(#[from] MessageFormatError), } diff --git a/comms/dht/src/store_forward/error.rs b/comms/dht/src/store_forward/error.rs index ac4e70ff74..81455d4882 100644 --- a/comms/dht/src/store_forward/error.rs +++ b/comms/dht/src/store_forward/error.rs @@ -21,61 +21,64 @@ // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. use crate::{actor::DhtActorError, envelope::DhtMessageError, outbound::DhtOutboundError, storage::StorageError}; -use derive_error::Error; use prost::DecodeError; -use std::io; use tari_comms::{message::MessageError, peer_manager::PeerManagerError}; use tari_utilities::{byte_array::ByteArrayError, ciphers::cipher::CipherError}; +use thiserror::Error; #[derive(Debug, Error)] pub enum StoreAndForwardError { - DhtMessageError(DhtMessageError), - MessageError(MessageError), - PeerManagerError(PeerManagerError), - DhtOutboundError(DhtOutboundError), - /// Received stored message has an invalid destination + #[error("DhtMessageError: {0}")] + DhtMessageError(#[from] DhtMessageError), + #[error("MessageError: {0}")] + MessageError(#[from] MessageError), + #[error("PeerManagerError: {0}")] + PeerManagerError(#[from] PeerManagerError), + #[error("DhtOutboundError: {0}")] + DhtOutboundError(#[from] DhtOutboundError), + #[error("Received stored message has an invalid destination")] InvalidDestination, - /// Received stored message has an invalid origin signature + #[error("Received stored message has an invalid origin signature")] InvalidOriginMac, - /// Invalid envelope body + #[error("Invalid envelope body")] InvalidEnvelopeBody, - /// DHT header is invalid + #[error("DHT header is invalid")] InvalidDhtHeader, - /// Received stored message which is not encrypted + #[error("Received stored message which is not encrypted")] StoredMessageNotEncrypted, - /// Unable to decrypt received stored message + #[error("Unable to decrypt received stored message")] DecryptionFailed, - CipherError(CipherError), - DhtActorError(DhtActorError), - /// Received duplicate stored message + #[error("CipherError: {0}")] + CipherError(#[from] CipherError), + #[error("DhtActorError: {0}")] + DhtActorError(#[from] DhtActorError), + #[error("Received duplicate stored message")] DuplicateMessage, - CurrentThreadRuntimeInitializeFailed(io::Error), - /// Unable to decode message - DecodeError(DecodeError), - /// Dht header was not provided + #[error("Unable to decode message: {0}")] + DecodeError(#[from] DecodeError), + #[error("Dht header was not provided")] DhtHeaderNotProvided, - /// Failed to spawn blocking task - JoinError(tokio::task::JoinError), - /// Message origin is for all forwarded messages + #[error("Message origin is for all forwarded messages")] MessageOriginRequired, - /// The message was malformed + #[error("The message was malformed")] MalformedMessage, - StorageError(StorageError), - /// The store and forward service requester channel closed + #[error("StorageError: {0}")] + StorageError(#[from] StorageError), + #[error("The store and forward service requester channel closed")] RequesterChannelClosed, - /// The request was cancelled by the store and forward service + #[error("The request was cancelled by the store and forward service")] RequestCancelled, - /// The message was not valid for store and forward + #[error("The message was not valid for store and forward")] InvalidStoreMessage, - /// The envelope version is invalid + #[error("The envelope version is invalid")] InvalidEnvelopeVersion, - MalformedNodeId(ByteArrayError), - /// NodeDistance threshold was invalid + #[error("MalformedNodeId: {0}")] + MalformedNodeId(#[from] ByteArrayError), + #[error("NodeDistance threshold was invalid")] InvalidNodeDistanceThreshold, - /// DHT message type should not have been forwarded + #[error("DHT message type should not have been forwarded")] InvalidDhtMessageType, - /// Failed to send request for store and forward messages - #[error(no_from)] + #[error("Failed to send request for store and forward messages: {0}")] RequestMessagesFailed(DhtOutboundError), } diff --git a/comms/dht/src/store_forward/saf_handler/task.rs b/comms/dht/src/store_forward/saf_handler/task.rs index 115f260ba1..d4c21f4f99 100644 --- a/comms/dht/src/store_forward/saf_handler/task.rs +++ b/comms/dht/src/store_forward/saf_handler/task.rs @@ -517,16 +517,12 @@ where S: Service let origin_mac = OriginMac::decode(origin_mac_body)?; let public_key = CommsPublicKey::from_bytes(&origin_mac.public_key).map_err(|_| StoreAndForwardError::InvalidOriginMac)?; - signature::verify(&public_key, &origin_mac.signature, body) - .map_err(|_| StoreAndForwardError::InvalidOriginMac) - .and_then(|is_valid| { - if is_valid { - Ok(()) - } else { - Err(StoreAndForwardError::InvalidOriginMac) - } - })?; - Ok(public_key) + + if signature::verify(&public_key, &origin_mac.signature, body) { + Ok(public_key) + } else { + Err(StoreAndForwardError::InvalidOriginMac) + } } } diff --git a/comms/examples/tor.rs b/comms/examples/tor.rs index 3845b49ed5..f794ea6b83 100644 --- a/comms/examples/tor.rs +++ b/comms/examples/tor.rs @@ -1,6 +1,5 @@ use bytes::Bytes; use chrono::Utc; -use derive_error::Error; use futures::{ channel::{mpsc, mpsc::SendError}, SinkExt, @@ -22,6 +21,7 @@ use tari_comms::{ use tari_crypto::tari_utilities::message_format::MessageFormat; use tari_storage::{lmdb_store::LMDBBuilder, LMDBWrapper}; use tempdir::TempDir; +use thiserror::Error; use tokio::{runtime, task}; // Tor example for tari_comms. @@ -30,16 +30,21 @@ use tokio::{runtime, task}; #[derive(Debug, Error)] enum Error { - /// Invalid control port address provided. USAGE: tor_example 'Tor_multiaddress'. + #[error("Invalid control port address provided. USAGE: tor_example 'Tor_multiaddress'.")] InvalidArgControlPortAddress, - NodeIdentityError(NodeIdentityError), - HiddenServiceBuilderError(tor::HiddenServiceBuilderError), - CommsBuilderError(CommsBuilderError), - PeerManagerError(PeerManagerError), - /// Failed to send message - SendError(SendError), - JoinError(task::JoinError), - #[error(msg_embedded, no_from, non_std)] + #[error("NodeIdentityError: {0}")] + NodeIdentityError(#[from] NodeIdentityError), + #[error("HiddenServiceBuilderError: {0}")] + HiddenServiceBuilderError(#[from] tor::HiddenServiceBuilderError), + #[error("CommsBuilderError: {0}")] + CommsBuilderError(#[from] CommsBuilderError), + #[error("PeerManagerError: {0}")] + PeerManagerError(#[from] PeerManagerError), + #[error("Failed to send message")] + SendError(#[from] SendError), + #[error("JoinError: {0}")] + JoinError(#[from] task::JoinError), + #[error("{0}")] Custom(String), } diff --git a/comms/src/builder/error.rs b/comms/src/builder/error.rs index 58072a003b..cfad5cc51b 100644 --- a/comms/src/builder/error.rs +++ b/comms/src/builder/error.rs @@ -21,23 +21,27 @@ // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. use crate::{connection_manager::ConnectionManagerError, peer_manager::PeerManagerError}; -use derive_error::Error; +use thiserror::Error; #[derive(Debug, Error)] pub enum CommsBuilderError { - PeerManagerError(PeerManagerError), - ConnectionManagerError(ConnectionManagerError), - /// Node identity not set. Call `with_node_identity(node_identity)` on [CommsBuilder] + #[error("Peer manager error: {0}")] + PeerManagerError(#[from] PeerManagerError), + #[error("Connection manager error: {0}")] + ConnectionManagerError(#[from] ConnectionManagerError), + #[error("Node identity not set. Call `with_node_identity(node_identity)` on [CommsBuilder]")] NodeIdentityNotSet, - /// The PeerStorage was not provided to the CommsBuilder. Use `with_peer_storage` to set it. + #[error("The PeerStorage was not provided to the CommsBuilder. Use `with_peer_storage` to set it.")] PeerStorageNotProvided, - /// The messaging pipeline was not provided to the CommsBuilder. Use `with_messaging_pipeline` to set it. - /// pipeline. + #[error( + "The messaging pipeline was not provided to the CommsBuilder. Use `with_messaging_pipeline` to set it's \ + pipeline." + )] MessagingPiplineNotProvided, - /// Unable to receive a ConnectionManagerEvent within timeout + #[error("Unable to receive a ConnectionManagerEvent within timeout")] ConnectionManagerEventStreamTimeout, - /// ConnectionManagerEvent stream unexpectedly closed + #[error("ConnectionManagerEvent stream unexpectedly closed")] ConnectionManagerEventStreamClosed, - /// Receiving on ConnectionManagerEvent stream lagged unexpectedly + #[error("Receiving on ConnectionManagerEvent stream lagged unexpectedly")] ConnectionManagerEventStreamLagged, } diff --git a/comms/src/connection_manager/error.rs b/comms/src/connection_manager/error.rs index 49b1c2205b..897aca2990 100644 --- a/comms/src/connection_manager/error.rs +++ b/comms/src/connection_manager/error.rs @@ -25,58 +25,58 @@ use crate::{ peer_manager::PeerManagerError, protocol::{IdentityProtocolError, ProtocolError}, }; -use derive_error::Error; use futures::channel::mpsc; +use thiserror::Error; #[derive(Debug, Error, Clone)] pub enum ConnectionManagerError { - PeerManagerError(PeerManagerError), - #[error(msg_embedded, no_from, non_std)] + #[error("Peer manager error: {0}")] + PeerManagerError(#[from] PeerManagerError), + #[error("Peer connection error: {0}")] PeerConnectionError(String), - /// Cannot connect to peers which are not persisted in the peer manager database. + #[error("Cannot connect to peers which are not persisted in the peer manager database.")] PeerNotPersisted, - /// Failed to send request to ConnectionManagerActor. Channel closed. + #[error("Failed to send request to ConnectionManagerActor. Channel closed.")] SendToActorFailed, - /// Request was canceled before the response could be sent + #[error("Request was canceled before the response could be sent")] ActorRequestCanceled, - /// The dial reply channel was closed when sending a reply + #[error("The dial reply channel was closed when sending a reply")] DialReplyChannelClosed, - /// Failed to connect on all addresses for peer + #[error("Failed to connect on all addresses for peer")] DialConnectFailedAllAddresses, - /// Failed to connect to peer within the maximum number of attempts + #[error("Failed to connect to peer within the maximum number of attempts")] ConnectFailedMaximumAttemptsReached, - #[error(msg_embedded, no_from, non_std)] + #[error("Yamux connection error: {0}")] YamuxConnectionError(String), - /// Establisher channel is closed or full - /// Failed to perform yamux upgrade on socket - #[error(msg_embedded, no_from, non_std)] + #[error("Failed to perform yamux upgrade on socket: {0}")] YamuxUpgradeFailure(String), - /// Establisher channel is closed or full + #[error("Establisher channel is closed or full")] EstablisherChannelError, - #[error(msg_embedded, no_from, non_std)] + #[error("Transport error: {0}")] TransportError(String), - /// The peer authenticated to a public key which did not match the dialed peer's public key + #[error("The peer authenticated to a public key which did not match the dialed peer's public key")] DialedPublicKeyMismatch, - /// The noise transport failed to provide a valid static public key for the peer + #[error("The noise transport failed to provide a valid static public key for the peer")] InvalidStaticPublicKey, // This is a String because we need this error to be clonable so that we can // send the same response to multiple requesters - #[error(msg_embedded, no_from, non_std)] + #[error("Noise error: {0}")] NoiseError(String), - /// Incoming listener stream unexpectedly closed + #[error("Incoming listener stream unexpectedly closed")] IncomingListenerStreamClosed, - /// The peer offered a NodeId that failed to validate against it's public key + #[error("The peer offered a NodeId that failed to validate against it's public key")] PeerIdentityInvalidNodeId, - /// Peer is banned, denying connection + #[error("Peer is banned, denying connection")] PeerBanned, - /// Unable to parse any of the network addresses offered by the connecting peer + #[error("Unable to parse any of the network addresses offered by the connecting peer")] PeerIdentityNoValidAddresses, - IdentityProtocolError(IdentityProtocolError), - /// The dial was cancelled + #[error("Identity protocol failed: {0}")] + IdentityProtocolError(#[from] IdentityProtocolError), + #[error("The dial was cancelled")] DialCancelled, - #[error(msg_embedded, no_from, non_std)] + #[error("Invalid multiaddr: {0}")] InvalidMultiaddr(String), - /// Failed to send wire format byte + #[error("Failed to send wire format byte")] WireFormatSendFailed, } @@ -88,7 +88,7 @@ impl From for ConnectionManagerError { impl From for ConnectionManagerError { fn from(err: noise::NoiseError) -> Self { - ConnectionManagerError::NoiseError(err.to_friendly_string()) + ConnectionManagerError::NoiseError(err.to_string()) } } @@ -100,10 +100,12 @@ impl From for ConnectionManagerError { #[derive(Debug, Error)] pub enum PeerConnectionError { - YamuxConnectionError(yamux::ConnectionError), - /// Internal oneshot reply channel was unexpectedly cancelled + #[error("Yamux connection error: {0}")] + YamuxConnectionError(#[from] yamux::ConnectionError), + #[error("Internal oneshot reply channel was unexpectedly cancelled")] InternalReplyCancelled, - /// Failed to send internal request - InternalRequestSendFailed(mpsc::SendError), - ProtocolError(ProtocolError), + #[error("Failed to send internal request: {0}")] + InternalRequestSendFailed(#[from] mpsc::SendError), + #[error("Protocol error: {0}")] + ProtocolError(#[from] ProtocolError), } diff --git a/comms/src/connectivity/error.rs b/comms/src/connectivity/error.rs index 5ca5cada0c..fc88d68feb 100644 --- a/comms/src/connectivity/error.rs +++ b/comms/src/connectivity/error.rs @@ -21,18 +21,20 @@ // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. use crate::{connection_manager::ConnectionManagerError, peer_manager::PeerManagerError}; -use derive_error::Error; +use thiserror::Error; #[derive(Debug, Error, Clone)] pub enum ConnectivityError { - /// Cannot send request because ConnectivityActor disconnected + #[error("Cannot send request because ConnectivityActor disconnected")] ActorDisconnected, - /// Response was unexpectedly cancelled + #[error("Response was unexpectedly cancelled")] ActorResponseCancelled, - PeerManagerError(PeerManagerError), - ConnectionFailed(ConnectionManagerError), - /// Connectivity event stream closed unexpectedly + #[error("PeerManagerError: {0}")] + PeerManagerError(#[from] PeerManagerError), + #[error("ConnectionFailed: {0}")] + ConnectionFailed(#[from] ConnectionManagerError), + #[error("Connectivity event stream closed unexpectedly")] ConnectivityEventStreamClosed, - /// Timeout while waiting for ONLINE connectivity + #[error("Timeout while waiting for ONLINE connectivity")] OnlineWaitTimeout, } diff --git a/comms/src/message/error.rs b/comms/src/message/error.rs index f56c4cdb4d..da76740f5f 100644 --- a/comms/src/message/error.rs +++ b/comms/src/message/error.rs @@ -20,39 +20,11 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -use crate::peer_manager::node_id::NodeIdError; -use derive_error::Error; use prost::DecodeError; -use tari_crypto::{ - signatures::SchnorrSignatureError, - tari_utilities::{ciphers::cipher::CipherError, message_format::MessageFormatError}, -}; +use thiserror::Error; -// TODO: only used by control service, so belongs in that module #[derive(Error, Debug)] pub enum MessageError { - /// Multipart message contained an invalid number of frames - InvalidMultipartMessageLength, - /// Failed to serialize message - SerializeFailed, - /// Failed to deserialize message - DeserializeFailed, - /// An error occurred serialising an object into binary - BinarySerializeError, - /// An error occurred deserialising binary data into an object - BinaryDeserializeError, - MessageFormatError(MessageFormatError), - SchnorrSignatureError(SchnorrSignatureError), - /// Failed to Encode or Decode the message using the Cipher - CipherError(CipherError), - NodeIdError(NodeIdError), - /// Problem initializing the RNG - RngError, - - /// The header contained an invalid public key - InvalidHeaderPublicKey, - /// Failed to decode protobuf message - DecodeError(DecodeError), - /// Failed to decode message part of envelope body - EnvelopeBodyDecodeFailed, + #[error("Failed to decode protobuf message: {0}")] + DecodeError(#[from] DecodeError), } diff --git a/comms/src/noise/error.rs b/comms/src/noise/error.rs index 8157982098..dd274f9e5d 100644 --- a/comms/src/noise/error.rs +++ b/comms/src/noise/error.rs @@ -20,21 +20,13 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -use derive_error::Error; use std::io; +use thiserror::Error; #[derive(Debug, Error)] pub enum NoiseError { - SnowError(snow::Error), - #[error(no_from)] + #[error("Snow Error: {0}")] + SnowError(#[from] snow::Error), + #[error("Handshake Failed: {0}")] HandshakeFailed(io::Error), } - -impl NoiseError { - pub fn to_friendly_string(&self) -> String { - match self { - NoiseError::SnowError(err) => format!("SnowError: {:?}", err), - NoiseError::HandshakeFailed(err) => format!("HandshakeFailed: {:?}", err), - } - } -} diff --git a/comms/src/peer_manager/error.rs b/comms/src/peer_manager/error.rs index 3e08776248..58b5dbaf85 100644 --- a/comms/src/peer_manager/error.rs +++ b/comms/src/peer_manager/error.rs @@ -20,18 +20,18 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE -use derive_error::Error; use std::sync::PoisonError; use tari_storage::KeyValStoreError; +use thiserror::Error; #[derive(Debug, Error, Clone)] pub enum PeerManagerError { - /// The requested peer does not exist + #[error("The requested peer does not exist")] PeerNotFoundError, - /// The peer has been banned + #[error("The peer has been banned")] BannedPeer, - // An problem has been encountered with the database - DatabaseError(KeyValStoreError), + #[error("An problem has been encountered with the database: {0}")] + DatabaseError(#[from] KeyValStoreError), } impl PeerManagerError { diff --git a/comms/src/peer_manager/node_id.rs b/comms/src/peer_manager/node_id.rs index 3011638cc3..1f1d704779 100644 --- a/comms/src/peer_manager/node_id.rs +++ b/comms/src/peer_manager/node_id.rs @@ -24,9 +24,9 @@ use blake2::{ digest::{Input, VariableOutput}, VarBlake2b, }; -use derive_error::Error; use serde::{de, Deserialize, Deserializer, Serialize}; use std::{ + cmp, cmp::Ordering, convert::{TryFrom, TryInto}, fmt, @@ -38,6 +38,7 @@ use tari_crypto::tari_utilities::{ ByteArray, ByteArrayError, }; +use thiserror::Error; const NODE_ID_ARRAY_SIZE: usize = 13; // 104-bit as per RFC-0151 type NodeIdArray = [u8; NODE_ID_ARRAY_SIZE]; @@ -46,9 +47,10 @@ pub type NodeDistance = XorDistance; // or HammingDistance #[derive(Debug, Error, Clone)] pub enum NodeIdError { + #[error("Incorrect byte count (expected {} bytes)", NODE_ID_ARRAY_SIZE)] IncorrectByteCount, - OutOfBounds, - DigestError, + #[error("Invalid digest output size")] + InvalidDigestOutputSize, } //------------------------------------- XOR Metric -----------------------------------------------// @@ -210,7 +212,7 @@ impl NodeId { /// Derive a node id from a public key: node_id=hash(public_key) pub fn from_key(key: &K) -> Result { let bytes = key.as_bytes(); - let mut hasher = VarBlake2b::new(NODE_ID_ARRAY_SIZE).map_err(|_| NodeIdError::DigestError)?; + let mut hasher = VarBlake2b::new(NODE_ID_ARRAY_SIZE).map_err(|_| NodeIdError::InvalidDigestOutputSize)?; hasher.input(bytes); let v = hasher.vec_result(); Self::try_from(v.as_slice()) @@ -227,10 +229,8 @@ impl NodeId { } /// Find and return the indices of the K nearest neighbours from the provided node id list - pub fn closest_indices(&self, node_ids: &[NodeId], k: usize) -> Result, NodeIdError> { - if k > node_ids.len() { - return Err(NodeIdError::OutOfBounds); - } + pub fn closest_indices(&self, node_ids: &[NodeId], k: usize) -> Vec { + let k = cmp::min(k, node_ids.len()); let mut indices: Vec = Vec::with_capacity(node_ids.len()); let mut dists: Vec = Vec::with_capacity(node_ids.len()); for (i, node_id) in node_ids.iter().enumerate() { @@ -248,17 +248,17 @@ impl NodeId { } nearest_node_indices.push(indices[i]); } - Ok(nearest_node_indices) + nearest_node_indices } /// Find and return the node ids of the K nearest neighbours from the provided node id list - pub fn closest(&self, node_ids: &[NodeId], k: usize) -> Result, NodeIdError> { - let nearest_node_indices = self.closest_indices(&node_ids.to_vec(), k)?; + pub fn closest(&self, node_ids: &[NodeId], k: usize) -> Vec { + let nearest_node_indices = self.closest_indices(&node_ids.to_vec(), k); let mut nearest_node_ids: Vec = Vec::with_capacity(nearest_node_indices.len()); for nearest in nearest_node_indices { nearest_node_ids.push(node_ids[nearest].clone()); } - Ok(nearest_node_ids) + nearest_node_ids } pub fn into_inner(self) -> NodeIdArray { @@ -495,34 +495,30 @@ mod test { let node_id = NodeId::try_from(&[169, 125, 200, 137, 210, 73, 241, 238, 25, 108, 8, 48, 66][..]).unwrap(); let k = 3; - match node_id.closest(&node_ids, k) { - Ok(knn_node_ids) => { - println!(" KNN = {:?}", knn_node_ids); - assert_eq!(knn_node_ids.len(), k); - // XOR metric nearest neighbours - assert_eq!(knn_node_ids[0].0, [ - 173, 218, 34, 188, 211, 173, 235, 82, 18, 159, 55, 47, 242 - ]); - assert_eq!(knn_node_ids[1].0, [ - 186, 43, 62, 14, 60, 214, 9, 180, 145, 122, 55, 160, 83 - ]); - assert_eq!(knn_node_ids[2].0, [ - 143, 189, 32, 210, 30, 231, 82, 5, 86, 85, 28, 82, 154 - ]); - // Hamming distance nearest neighbours - // assert_eq!(knn_node_ids[0].0, [ - // 75, 146, 162, 130, 22, 63, 247, 182, 156, 103, 174, 32, 134 - // ]); - // assert_eq!(knn_node_ids[1].0, [ - // 134, 116, 78, 53, 246, 206, 200, 147, 126, 96, 54, 113, 67 - // ]); - // assert_eq!(knn_node_ids[2].0, [ - // 144, 28, 106, 112, 220, 197, 216, 119, 9, 217, 42, 77, 159 - // ]); - }, - Err(_e) => assert!(false), - }; - assert!(node_id.closest(&node_ids, node_ids.len() + 1).is_err()); + let knn_node_ids = node_id.closest(&node_ids, k); + println!(" KNN = {:?}", knn_node_ids); + assert_eq!(knn_node_ids.len(), k); + // XOR metric nearest neighbours + assert_eq!(knn_node_ids[0].0, [ + 173, 218, 34, 188, 211, 173, 235, 82, 18, 159, 55, 47, 242 + ]); + assert_eq!(knn_node_ids[1].0, [ + 186, 43, 62, 14, 60, 214, 9, 180, 145, 122, 55, 160, 83 + ]); + assert_eq!(knn_node_ids[2].0, [ + 143, 189, 32, 210, 30, 231, 82, 5, 86, 85, 28, 82, 154 + ]); + // Hamming distance nearest neighbours + // assert_eq!(knn_node_ids[0].0, [ + // 75, 146, 162, 130, 22, 63, 247, 182, 156, 103, 174, 32, 134 + // ]); + // assert_eq!(knn_node_ids[1].0, [ + // 134, 116, 78, 53, 246, 206, 200, 147, 126, 96, 54, 113, 67 + // ]); + // assert_eq!(knn_node_ids[2].0, [ + // 144, 28, 106, 112, 220, 197, 216, 119, 9, 217, 42, 77, 159 + // ]); + assert_eq!(node_id.closest(&node_ids, node_ids.len() + 1).len(), node_ids.len()); } #[test] diff --git a/comms/src/peer_manager/node_identity.rs b/comms/src/peer_manager/node_identity.rs index f0e8eecdd5..a544f77f64 100644 --- a/comms/src/peer_manager/node_identity.rs +++ b/comms/src/peer_manager/node_identity.rs @@ -30,7 +30,6 @@ use crate::{ }, types::{CommsPublicKey, CommsSecretKey}, }; -use derive_error::Error; use multiaddr::Multiaddr; use rand::{CryptoRng, Rng}; use serde::{Deserialize, Serialize}; @@ -39,12 +38,14 @@ use tari_crypto::{ keys::{PublicKey, SecretKey}, tari_utilities::hex::serialize_to_hex, }; +use thiserror::Error; #[derive(Debug, Error)] pub enum NodeIdentityError { - NodeIdError(NodeIdError), - /// The Thread Safety has been breached and the data access has become poisoned - PoisonedAccess, + #[error("NodeIdError: {0}")] + NodeIdError(#[from] NodeIdError), + #[error("Address lock has been poisoned")] + AddressLockPoisoned, } /// The public and private identity of this node on the network @@ -111,7 +112,7 @@ impl NodeIdentity { *self .public_address .write() - .map_err(|_| NodeIdentityError::PoisonedAccess)? = address; + .map_err(|_| NodeIdentityError::AddressLockPoisoned)? = address; Ok(()) } diff --git a/comms/src/pipeline/builder.rs b/comms/src/pipeline/builder.rs index f069c33398..1005142e32 100644 --- a/comms/src/pipeline/builder.rs +++ b/comms/src/pipeline/builder.rs @@ -24,8 +24,8 @@ use crate::{ message::{InboundMessage, OutboundMessage}, pipeline::SinkService, }; -use derive_error::Error; use futures::channel::mpsc; +use thiserror::Error; use tower::Service; const DEFAULT_MAX_CONCURRENT_TASKS: usize = 50; @@ -157,9 +157,9 @@ pub struct Config { #[derive(Debug, Error)] pub enum PipelineBuilderError { - /// Inbound pipeline was not provided + #[error("Inbound pipeline was not provided")] InboundNotProvided, - /// Outbound pipeline was not provided + #[error("Outbound pipeline was not provided")] OutboundPipelineNotProvided, } diff --git a/comms/src/protocol/error.rs b/comms/src/protocol/error.rs index 43e5bbe0de..80c98bd22f 100644 --- a/comms/src/protocol/error.rs +++ b/comms/src/protocol/error.rs @@ -20,35 +20,25 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -use derive_error::Error; -use futures::channel::mpsc; use std::io; +use thiserror::Error; #[derive(Debug, Error)] pub enum ProtocolError { - IoError(io::Error), - /// The ProtocolId was longer than 255 + #[error("IO error: {0}")] + IoError(#[from] io::Error), + #[error("The ProtocolId was longer than {}", u8::max_value())] ProtocolIdTooLong, - /// Protocol negotiation failed because the peer did not accept any protocols + #[error("Protocol negotiation failed because the peer did not accept any protocols")] ProtocolOutboundNegotiationFailed, - /// Protocol negotiation failed because the peer did not offer any protocols supported by this node + #[error("Protocol negotiation failed because the peer did not offer any protocols supported by this node")] ProtocolInboundNegotiationFailed, - /// Optimistic protocol negotiation failed because the peer did not offer a protocol supported by this node + #[error("Optimistic protocol negotiation failed because the peer did not offer a protocol supported by this node")] ProtocolOptimisticNegotiationFailed, - /// Protocol negotiation terminated by peer + #[error("Protocol negotiation terminated by peer")] ProtocolNegotiationTerminatedByPeer, - /// Protocol was not registered + #[error("Protocol was not registered")] ProtocolNotRegistered, - SendError(mpsc::SendError), -} - -impl ProtocolError { - pub fn to_friendly_string(&self) -> String { - use ProtocolError::*; - match self { - IoError(err) => format!("IoError: {:?}", err), - SendError(err) => format!("SendError: {:?}", err), - err => format!("{}", err), - } - } + #[error("Failed to send notification because notification sender disconnected")] + NotificationSenderDisconnected, } diff --git a/comms/src/protocol/identity.rs b/comms/src/protocol/identity.rs index bd52299620..d207bd029e 100644 --- a/comms/src/protocol/identity.rs +++ b/comms/src/protocol/identity.rs @@ -27,12 +27,12 @@ use crate::{ proto::identity::PeerIdentityMsg, protocol::{ProtocolError, ProtocolId, ProtocolNegotiation}, }; -use derive_error::Error; use futures::{AsyncRead, AsyncWrite, SinkExt, StreamExt}; use log::*; use prost::Message; use std::io; use tari_crypto::tari_utilities::ByteArray; +use thiserror::Error; use tokio_util::codec::{Framed, LengthDelimitedCodec}; pub static IDENTITY_PROTOCOL: ProtocolId = ProtocolId::from_static(b"/tari/identity/1.0.0"); @@ -105,21 +105,21 @@ where #[derive(Debug, Error, Clone)] pub enum IdentityProtocolError { - #[error(msg_embedded, no_from, non_std)] + #[error("IoError: {0}")] IoError(String), - #[error(msg_embedded, no_from, non_std)] + #[error("ProtocolError: {0}")] ProtocolError(String), - #[error(msg_embedded, no_from, non_std)] + #[error("ProtobufDecodeError: {0}")] ProtobufDecodeError(String), - /// Failed to encode protobuf message + #[error("Failed to encode protobuf message")] ProtobufEncodingError, - /// Peer unexpectedly closed the connection + #[error("Peer unexpectedly closed the connection")] PeerUnexpectedCloseConnection, } impl From for IdentityProtocolError { fn from(err: ProtocolError) -> Self { - IdentityProtocolError::ProtocolError(err.to_friendly_string()) + IdentityProtocolError::ProtocolError(err.to_string()) } } diff --git a/comms/src/protocol/messaging/error.rs b/comms/src/protocol/messaging/error.rs index ff595332f8..03cc926433 100644 --- a/comms/src/protocol/messaging/error.rs +++ b/comms/src/protocol/messaging/error.rs @@ -20,31 +20,26 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -use crate::{ - connection_manager::PeerConnectionError, - message::MessageError, - peer_manager::PeerManagerError, - protocol::ProtocolError, -}; -use derive_error::Error; +use crate::{connection_manager::PeerConnectionError, peer_manager::PeerManagerError, protocol::ProtocolError}; +use thiserror::Error; #[derive(Debug, Error)] pub enum InboundMessagingError { - PeerManagerError(PeerManagerError), - /// Failed to decode message - MessageDecodeError(prost::DecodeError), - MessageError(MessageError), + #[error("PeerManagerError: {0}")] + PeerManagerError(#[from] PeerManagerError), + #[error("Failed to decode message: {0}")] + MessageDecodeError(#[from] prost::DecodeError), } #[derive(Debug, Error)] pub enum MessagingProtocolError { - /// Failed to send message - #[error(no_from, non_std)] + #[error("Failed to send message")] MessageSendFailed, - ProtocolError(ProtocolError), - PeerConnectionError(PeerConnectionError), - /// Failed to dial peer + #[error("ProtocolError: {0}")] + ProtocolError(#[from] ProtocolError), + #[error("PeerConnectionError: {0}")] + PeerConnectionError(#[from] PeerConnectionError), + #[error("Failed to dial peer")] PeerDialFailed, - /// Failure when sending on an outbound substream + #[error("Failure when sending on an outbound substream")] OutboundSubstreamFailure, - MessageError(MessageError), } diff --git a/comms/src/protocol/messaging/protocol.rs b/comms/src/protocol/messaging/protocol.rs index d88673602b..f11bcefcb6 100644 --- a/comms/src/protocol/messaging/protocol.rs +++ b/comms/src/protocol/messaging/protocol.rs @@ -36,7 +36,6 @@ use crate::{ PeerManager, }; use bytes::Bytes; -use derive_error::Error; use futures::{channel::mpsc, stream::Fuse, AsyncRead, AsyncWrite, SinkExt, StreamExt}; use log::*; use std::{ @@ -46,6 +45,7 @@ use std::{ time::Duration, }; use tari_shutdown::{Shutdown, ShutdownSignal}; +use thiserror::Error; use tokio::sync::broadcast; use tokio_util::codec::{Framed, LengthDelimitedCodec}; @@ -76,11 +76,11 @@ pub enum MessagingRequest { /// occurred #[derive(Debug, Error, Copy, Clone)] pub enum SendFailReason { - /// Dial was attempted, but failed + #[error("Dial was attempted, but failed")] PeerDialFailed, - /// Failed to open a messaging substream to peer + #[error("Failed to open a messaging substream to peer")] SubstreamOpenFailed, - /// Failed to send on substream channel + #[error("Failed to send on substream channel")] SubstreamSendFailed, } diff --git a/comms/src/protocol/protocols.rs b/comms/src/protocol/protocols.rs index 40a1eb6c2e..0c2e9fd8fc 100644 --- a/comms/src/protocol/protocols.rs +++ b/comms/src/protocol/protocols.rs @@ -95,7 +95,10 @@ impl Protocols { { match self.protocols.get_mut(protocol) { Some(sender) => { - sender.send(ProtocolNotification::new(protocol.clone(), event)).await?; + sender + .send(ProtocolNotification::new(protocol.clone(), event)) + .await + .map_err(|_| ProtocolError::NotificationSenderDisconnected)?; Ok(()) }, None => Err(ProtocolError::ProtocolNotRegistered), diff --git a/comms/src/socks/error.rs b/comms/src/socks/error.rs index f86c10fb27..5b345a832b 100644 --- a/comms/src/socks/error.rs +++ b/comms/src/socks/error.rs @@ -20,49 +20,47 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -use derive_error::Error; +use std::io; +use thiserror::Error; #[derive(Debug, Error)] pub enum SocksError { - /// Failure caused by an IO error. - Io(std::io::Error), - /// Failure due to invalid target address. - #[error(no_from, non_std)] + #[error("Failure caused by an IO error: {0}")] + Io(#[from] io::Error), + #[error("Failure due to invalid target address: {0}.")] InvalidTargetAddress(&'static str), - /// Proxy server unreachable. + #[error("Proxy server unreachable.")] ProxyServerUnreachable, - /// Proxy server returns an invalid version number. + #[error("Proxy server returns an invalid version number.")] InvalidResponseVersion, - /// No acceptable auth methods + #[error("No acceptable auth methods")] NoAcceptableAuthMethods, - /// Unknown auth method + #[error("Unknown auth method")] UnknownAuthMethod, - /// General SOCKS server failure + #[error("General SOCKS server failure")] GeneralSocksServerFailure, - /// Connection not allowed by ruleset + #[error("Connection not allowed by ruleset")] ConnectionNotAllowedByRuleset, - /// Network unreachable + #[error("Network unreachable")] NetworkUnreachable, - /// Host unreachable + #[error("Host unreachable")] HostUnreachable, - /// Connection refused + #[error("Connection refused")] ConnectionRefused, - /// TTL expired + #[error("TTL expired")] TtlExpired, - /// Command not supported + #[error("Command not supported")] CommandNotSupported, - /// Address type not supported + #[error("Address type not supported")] AddressTypeNotSupported, - /// Unknown error + #[error("Unknown error")] UnknownError, - /// Invalid reserved byte + #[error("Invalid reserved byte")] InvalidReservedByte, - /// Unknown address type + #[error("Unknown address type")] UnknownAddressType, - // Invalid authentication values. - #[error(msg_embedded, no_from, non_std)] + #[error("Invalid authentication values: {0}.")] InvalidAuthValues(String), - /// Password auth failure - #[error(no_from, non_std)] + #[error("Password auth failure (code={0})")] PasswordAuthFailure(u8), } diff --git a/comms/src/test_utils/factories/mod.rs b/comms/src/test_utils/factories/mod.rs index c72875257b..f1df91db3e 100644 --- a/comms/src/test_utils/factories/mod.rs +++ b/comms/src/test_utils/factories/mod.rs @@ -20,8 +20,8 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -use derive_error::Error; use std::fmt::Debug; +use thiserror::Error; #[macro_use] mod macros; @@ -39,8 +39,7 @@ pub trait TestFactory: Default { #[derive(Debug, Error)] pub enum TestFactoryError { - /// Failed to build object - #[error(msg_embedded, non_std, no_from)] + #[error("Failed to build object: {0}")] BuildFailed(String), } diff --git a/comms/src/tor/control_client/error.rs b/comms/src/tor/control_client/error.rs index 0f72ccf47c..6973a4d530 100644 --- a/comms/src/tor/control_client/error.rs +++ b/comms/src/tor/control_client/error.rs @@ -20,32 +20,33 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. use super::parsers::ParseError; -use derive_error::Error; use std::io; +use thiserror::Error; use tokio_util::codec::LinesCodecError; #[derive(Debug, Error)] pub enum TorClientError { - /// Failed to read/write line to socket. The maximum line length was exceeded. + #[error("Failed to read/write line to socket. The maximum line length was exceeded.")] MaxLineLengthExceeded, - Io(io::Error), - /// Command failed - #[error(no_from, non_std)] + #[error("IO Error: {0}")] + Io(#[from] io::Error), + #[error("Command failed: {0}")] TorCommandFailed(String), - /// Tor control port connection unexpectedly closed + #[error("Tor control port connection unexpectedly closed")] UnexpectedEof, - ParseError(ParseError), - /// The server returned no response + #[error("Parse error: {0}")] + ParseError(#[from] ParseError), + #[error("The server returned no response")] ServerNoResponse, - /// Server did not return a ServiceID for ADD_ONION command + #[error("Server did not return a ServiceID for ADD_ONION command")] AddOnionNoServiceId, - /// The given service id was invalid + #[error("The given service id was invalid")] InvalidServiceId, - /// Onion address is exists + #[error("Onion address is exists")] OnionAddressCollision, - /// Response returned an no value for key + #[error("Response returned an no value for key")] KeyValueNoValue, - /// The command sender disconnected + #[error("The command sender disconnected")] CommandSenderDisconnected, } diff --git a/comms/src/tor/control_client/event.rs b/comms/src/tor/control_client/event.rs index 0d04a78020..53e6bc9722 100644 --- a/comms/src/tor/control_client/event.rs +++ b/comms/src/tor/control_client/event.rs @@ -21,11 +21,13 @@ // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. use super::response::ResponseLine; -use derive_error::Error; +use thiserror::Error; #[derive(Debug, Error)] pub enum ControlEventError { + #[error("Received an empty response")] EmptyResponse, + #[error("Received invalid event data")] InvalidEventData, } diff --git a/comms/src/tor/hidden_service/builder.rs b/comms/src/tor/hidden_service/builder.rs index f880e1f46f..7e56bd3cb9 100644 --- a/comms/src/tor/hidden_service/builder.rs +++ b/comms/src/tor/hidden_service/builder.rs @@ -33,18 +33,19 @@ use crate::{ }, }; use bitflags::bitflags; -use derive_error::Error; use log::*; +use thiserror::Error; const LOG_TARGET: &str = "comms::tor::hidden_service"; #[derive(Debug, Error)] pub enum HiddenServiceBuilderError { - /// The proxied port mapping was not provided. Use `with_proxied_port_mapping` to set it. + #[error("The proxied port mapping was not provided. Use `with_proxied_port_mapping` to set it.")] ProxiedPortMappingNotProvided, - /// The control server address was not provided. Use `with_control_server_address` to set it. + #[error("The control server address was not provided. Use `with_control_server_address` to set it.")] TorControlServerAddressNotProvided, - HiddenServiceControllerError(HiddenServiceControllerError), + #[error("HiddenServiceControllerError: {0}")] + HiddenServiceControllerError(#[from] HiddenServiceControllerError), } bitflags! { diff --git a/comms/src/tor/hidden_service/controller.rs b/comms/src/tor/hidden_service/controller.rs index c24f71a4c9..ba74edccb9 100644 --- a/comms/src/tor/hidden_service/controller.rs +++ b/comms/src/tor/hidden_service/controller.rs @@ -38,27 +38,28 @@ use crate::{ }, utils::multiaddr::socketaddr_to_multiaddr, }; -use derive_error::Error; use futures::{future, future::Either, pin_mut, StreamExt}; use log::*; use std::{net::SocketAddr, time::Duration}; use tari_shutdown::{Shutdown, ShutdownSignal}; +use thiserror::Error; use tokio::{sync::broadcast, task, time}; const LOG_TARGET: &str = "comms::tor::hidden_service_controller"; #[derive(Debug, Error)] pub enum HiddenServiceControllerError { - /// Tor client is not connected + #[error("Tor client is not connected")] NotConnected, - /// Failed to parse SOCKS address returned by control port + #[error("Failed to parse SOCKS address returned by control port")] FailedToParseSocksAddress, - TorClientError(TorClientError), - /// Unable to connect to the Tor control port + #[error("TorClientError: {0}")] + TorClientError(#[from] TorClientError), + #[error("Unable to connect to the Tor control port")] TorControlPortOffline, - /// The given tor service id is not a valid detached service id + #[error("The given tor service id is not a valid detached service id")] InvalidDetachedServiceId, - /// The shutdown signal interrupted the HiddenServiceController + #[error("The shutdown signal interrupted the HiddenServiceController")] ShutdownSignalInterrupt, } diff --git a/comms/src/utils/signature.rs b/comms/src/utils/signature.rs index 683e9e3c19..2224a1bf6b 100644 --- a/comms/src/utils/signature.rs +++ b/comms/src/utils/signature.rs @@ -20,10 +20,7 @@ // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE // USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -use crate::{ - message::MessageError, - types::{Challenge, CommsPublicKey}, -}; +use crate::types::{Challenge, CommsPublicKey}; use digest::Digest; use rand::{CryptoRng, Rng}; use tari_crypto::{ @@ -47,10 +44,13 @@ where } /// Verify that the signature is valid for the message body -pub fn verify(public_key: &CommsPublicKey, signature: &[u8], body: B) -> Result +pub fn verify(public_key: &CommsPublicKey, signature: &[u8], body: B) -> bool where B: AsRef<[u8]> { - let signature = SchnorrSignature::::K>::from_binary(signature) - .map_err(MessageError::MessageFormatError)?; - let challenge = Challenge::new().chain(body).result().to_vec(); - Ok(signature.verify_challenge(public_key, &challenge)) + match SchnorrSignature::::K>::from_binary(signature) { + Ok(signature) => { + let challenge = Challenge::new().chain(body).result().to_vec(); + signature.verify_challenge(public_key, &challenge) + }, + Err(_) => false, + } }