diff --git a/node/Cargo.lock b/node/Cargo.lock index 41788692..390ba435 100644 --- a/node/Cargo.lock +++ b/node/Cargo.lock @@ -1928,6 +1928,7 @@ dependencies = [ "storage", "tempfile", "test-casing", + "thiserror", "tokio", "tracing", "utils", diff --git a/node/actors/consensus/src/leader/replica_commit.rs b/node/actors/consensus/src/leader/replica_commit.rs index 82ab32b2..870da2b5 100644 --- a/node/actors/consensus/src/leader/replica_commit.rs +++ b/node/actors/consensus/src/leader/replica_commit.rs @@ -5,27 +5,41 @@ use network::io::{ConsensusInputMessage, Target}; use roles::validator; use tracing::instrument; -#[derive(thiserror::Error, Debug)] -#[allow(clippy::missing_docs_in_private_items)] +/// Errors that can occur when processing a "replica commit" message. +#[derive(Debug, thiserror::Error)] pub(crate) enum Error { + /// Unexpected proposal. #[error("unexpected proposal")] UnexpectedProposal, + /// Past view or phase. #[error("past view/phase (current view: {current_view:?}, current phase: {current_phase:?})")] Old { + /// Current view. current_view: validator::ViewNumber, + /// Current phase. current_phase: validator::Phase, }, + /// The processing node is not a lead for this message's view. #[error("we are not a leader for this message's view")] NotLeaderInView, + /// Duplicate message from a replica. #[error("duplicate message from a replica (existing message: {existing_message:?}")] DuplicateMessage { + /// Existing message from the same replica. existing_message: validator::ReplicaCommit, }, - #[error("number of received messages is below threshold. waiting for more (received: {num_messages:?}, threshold: {threshold:?}")] + /// Number of received messages is below threshold. + #[error( + "number of received messages is below threshold. waiting for more (received: {num_messages:?}, \ + threshold: {threshold:?}" + )] NumReceivedBelowThreshold { + /// Number of received messages. num_messages: usize, + /// Threshold for message count. threshold: usize, }, + /// Invalid message signature. #[error("invalid signature: {0:#}")] InvalidSignature(#[source] crypto::bls12_381::Error), } diff --git a/node/actors/consensus/src/leader/replica_prepare.rs b/node/actors/consensus/src/leader/replica_prepare.rs index 800bd331..67519427 100644 --- a/node/actors/consensus/src/leader/replica_prepare.rs +++ b/node/actors/consensus/src/leader/replica_prepare.rs @@ -7,34 +7,51 @@ use roles::validator; use std::collections::HashMap; use tracing::instrument; -#[derive(thiserror::Error, Debug)] -#[allow(clippy::missing_docs_in_private_items)] +/// Errors that can occur when processing a "replica prepare" message. +#[derive(Debug, thiserror::Error)] pub(crate) enum Error { + /// Past view or phase. #[error("past view/phase (current view: {current_view:?}, current phase: {current_phase:?})")] Old { + /// Current view. current_view: validator::ViewNumber, + /// Current phase. current_phase: validator::Phase, }, + /// The node is not a leader for this message's view. #[error("we are not a leader for this message's view")] NotLeaderInView, + /// Duplicate message from a replica. #[error("duplicate message from a replica (existing message: {existing_message:?}")] Exists { + /// Existing message from the same replica. existing_message: validator::ReplicaPrepare, }, - #[error("number of received messages below threshold. waiting for more (received: {num_messages:?}, threshold: {threshold:?}")] + /// Number of received messages is below a threshold. + #[error( + "number of received messages below threshold. waiting for more (received: {num_messages:?}, \ + threshold: {threshold:?}" + )] NumReceivedBelowThreshold { + /// Number of received messages. num_messages: usize, + /// Threshold for message count. threshold: usize, }, + /// High QC of a future view. #[error( "high QC of a future view (high QC view: {high_qc_view:?}, current view: {current_view:?}" )] HighQCOfFutureView { + /// Received high QC view. high_qc_view: validator::ViewNumber, + /// Current view. current_view: validator::ViewNumber, }, + /// Invalid message signature. #[error("invalid signature: {0:#}")] InvalidSignature(#[source] crypto::bls12_381::Error), + /// Invalid `HighQC` message. #[error("invalid high QC: {0:#}")] InvalidHighQC(#[source] anyhow::Error), } diff --git a/node/actors/consensus/src/replica/leader_commit.rs b/node/actors/consensus/src/replica/leader_commit.rs index 32cf70ce..bc73a82b 100644 --- a/node/actors/consensus/src/replica/leader_commit.rs +++ b/node/actors/consensus/src/replica/leader_commit.rs @@ -5,23 +5,34 @@ use concurrency::ctx; use roles::validator; use tracing::instrument; -#[derive(thiserror::Error, Debug)] -#[allow(clippy::missing_docs_in_private_items)] +/// Errors that can occur when processing a "leader commit" message. +#[derive(Debug, thiserror::Error)] pub(crate) enum Error { - #[error("invalid leader (correct leader: {correct_leader:?}, received leader: {received_leader:?})]")] + /// Invalid leader. + #[error( + "invalid leader (correct leader: {correct_leader:?}, received leader: {received_leader:?})" + )] InvalidLeader { + /// Correct leader. correct_leader: validator::PublicKey, + /// Received leader. received_leader: validator::PublicKey, }, + /// Past view of phase. #[error("past view/phase (current view: {current_view:?}, current phase: {current_phase:?})")] Old { + /// Current view. current_view: validator::ViewNumber, + /// Current phase. current_phase: validator::Phase, }, + /// Invalid message signature. #[error("invalid signature: {0:#}")] InvalidSignature(#[source] crypto::bls12_381::Error), + /// Invalid justification for the message. #[error("invalid justification: {0:#}")] InvalidJustification(#[source] anyhow::Error), + /// Internal error. Unlike other error types, this one isn't supposed to be easily recoverable. #[error("internal error: {0:#}")] Internal(#[from] anyhow::Error), } diff --git a/node/actors/consensus/src/replica/leader_prepare.rs b/node/actors/consensus/src/replica/leader_prepare.rs index 7eee6ac9..ec2c3b8e 100644 --- a/node/actors/consensus/src/replica/leader_prepare.rs +++ b/node/actors/consensus/src/replica/leader_prepare.rs @@ -7,61 +7,100 @@ use roles::validator; use std::collections::HashMap; use tracing::instrument; -#[derive(thiserror::Error, Debug)] -#[allow(clippy::missing_docs_in_private_items)] +/// Errors that can occur when processing a "leader prepare" message. +#[derive(Debug, thiserror::Error)] pub(crate) enum Error { - #[error("invalid leader (correct leader: {correct_leader:?}, received leader: {received_leader:?}])")] + /// Invalid leader. + #[error( + "invalid leader (correct leader: {correct_leader:?}, received leader: {received_leader:?})" + )] InvalidLeader { + /// Correct leader. correct_leader: validator::PublicKey, + /// Received leader. received_leader: validator::PublicKey, }, - #[error("message for a past view/phase (current view: {current_view:?}, current phase: {current_phase:?})")] + /// Message for a past view or phase. + #[error( + "message for a past view / phase (current view: {current_view:?}, current phase: {current_phase:?})" + )] Old { + /// Current view. current_view: validator::ViewNumber, + /// Current phase. current_phase: validator::Phase, }, + /// Invalid message signature. #[error("invalid signature: {0:#}")] InvalidSignature(#[source] crypto::bls12_381::Error), + /// Invalid `PrepareQC` message. #[error("invalid PrepareQC: {0:#}")] InvalidPrepareQC(#[source] anyhow::Error), + /// Invalid `HighQC` message. #[error("invalid high QC: {0:#}")] InvalidHighQC(#[source] anyhow::Error), + /// High QC of a future view. #[error( "high QC of a future view (high QC view: {high_qc_view:?}, current view: {current_view:?}" )] HighQCOfFutureView { + /// Received high QC view. high_qc_view: validator::ViewNumber, + /// Current view. current_view: validator::ViewNumber, }, + /// Previous proposal was not finalized. #[error("new block proposal when the previous proposal was not finalized")] ProposalWhenPreviousNotFinalized, - #[error("block proposal with invalid parent hash (correct parent hash: {correct_parent_hash:#?}, received parent hash: {received_parent_hash:#?}, block: {header:?})")] + /// Invalid parent hash. + #[error( + "block proposal with invalid parent hash (correct parent hash: {correct_parent_hash:#?}, \ + received parent hash: {received_parent_hash:#?}, block: {header:?})" + )] ProposalInvalidParentHash { + /// Correct parent hash. correct_parent_hash: validator::BlockHeaderHash, + /// Received parent hash. received_parent_hash: validator::BlockHeaderHash, + /// Header including the incorrect parent hash. header: validator::BlockHeader, }, - #[error("block proposal with non-sequential number (correct proposal number: {correct_number}, received proposal number: {received_number}, block: {header:?})")] + /// Non-sequential proposal number. + #[error( + "block proposal with non-sequential number (correct proposal number: {correct_number}, \ + received proposal number: {received_number}, block: {header:?})" + )] ProposalNonSequentialNumber { + /// Correct proposal number. correct_number: validator::BlockNumber, + /// Received proposal number. received_number: validator::BlockNumber, + /// Header including the incorrect proposal number. header: validator::BlockHeader, }, + /// Mismatched payload. #[error("block proposal with mismatched payload")] ProposalMismatchedPayload, + /// Oversized payload. #[error( "block proposal with an oversized payload (payload size: {payload_size}, block: {header:?}" )] ProposalOversizedPayload { + /// Size of the payload. payload_size: usize, + /// Proposal header corresponding to the payload. header: validator::BlockHeader, }, + /// Re-proposal without quorum. #[error("block re-proposal without quorum for the re-proposal")] ReproposalWithoutQuorum, + /// Re-proposal when the previous proposal was finalized. #[error("block re-proposal when the previous proposal was finalized")] ReproposalWhenFinalized, + /// Re-proposal of invalid block. #[error("block re-proposal of invalid block")] ReproposalInvalidBlock, + /// Internal error. Unlike other error types, this one isn't supposed to be easily recoverable. #[error("internal error: {0:#}")] Internal(#[from] anyhow::Error), } diff --git a/node/actors/network/src/consensus/handshake/mod.rs b/node/actors/network/src/consensus/handshake/mod.rs index d0eabab9..df12c477 100644 --- a/node/actors/network/src/consensus/handshake/mod.rs +++ b/node/actors/network/src/consensus/handshake/mod.rs @@ -35,8 +35,8 @@ impl ProtoFmt for Handshake { } } -/// Error returned by AuthStream::handshake. -#[derive(thiserror::Error, Debug)] +/// Error returned by handshake logic. +#[derive(Debug, thiserror::Error)] pub(super) enum Error { #[error("session id mismatch")] SessionIdMismatch, diff --git a/node/actors/network/src/gossip/handshake/mod.rs b/node/actors/network/src/gossip/handshake/mod.rs index c84b377c..f8d8ba83 100644 --- a/node/actors/network/src/gossip/handshake/mod.rs +++ b/node/actors/network/src/gossip/handshake/mod.rs @@ -41,15 +41,15 @@ impl ProtoFmt for Handshake { } } -/// Error returned by AuthStream::handshake. -#[derive(thiserror::Error, Debug)] +/// Error returned by gossip handshake logic. +#[derive(Debug, thiserror::Error)] pub(super) enum Error { #[error("session id mismatch")] SessionIdMismatch, #[error("unexpected peer")] PeerMismatch, #[error("validator signature")] - Signature(#[from] node::ErrInvalidSignature), + Signature(#[from] node::InvalidSignatureError), #[error("stream")] Stream(#[source] anyhow::Error), } diff --git a/node/actors/network/src/io.rs b/node/actors/network/src/io.rs index 8a3ff6ef..ab0a4f36 100644 --- a/node/actors/network/src/io.rs +++ b/node/actors/network/src/io.rs @@ -1,7 +1,6 @@ #![allow(missing_docs)] use concurrency::oneshot; use roles::{node, validator}; -use thiserror::Error; /// All the messages that other actors can send to the Network actor. #[derive(Debug)] @@ -84,7 +83,7 @@ impl SyncState { /// Errors returned from a [`GetBlockResponse`]. /// /// Note that these errors don't include network-level errors, only app-level ones. -#[derive(Debug, Error)] +#[derive(Debug, thiserror::Error)] pub enum GetBlockError { /// Transient error: the node doesn't have the requested L2 block and plans to get it in the future /// by syncing. diff --git a/node/actors/network/src/mux/mod.rs b/node/actors/network/src/mux/mod.rs index 358ad1f1..472d61ba 100644 --- a/node/actors/network/src/mux/mod.rs +++ b/node/actors/network/src/mux/mod.rs @@ -143,7 +143,7 @@ impl Mux { } /// Error returned by `Mux::run()`. -#[derive(thiserror::Error, Debug)] +#[derive(Debug, thiserror::Error)] #[allow(clippy::missing_docs_in_private_items)] pub(crate) enum RunError { #[error("config: {0:#}")] diff --git a/node/actors/network/src/mux/transient_stream.rs b/node/actors/network/src/mux/transient_stream.rs index d584f700..4fe33539 100644 --- a/node/actors/network/src/mux/transient_stream.rs +++ b/node/actors/network/src/mux/transient_stream.rs @@ -20,7 +20,7 @@ pub(crate) struct ReadStream(pub(super) sync::ExclusiveLock) pub(crate) struct WriteStream(pub(super) sync::ExclusiveLock); /// Error returned by `ReadStream::read` in case the stream has been closed by peer. -#[derive(thiserror::Error, Debug)] +#[derive(Debug, thiserror::Error)] #[error("end of stream")] pub(crate) struct EndOfStream; diff --git a/node/actors/sync_blocks/Cargo.toml b/node/actors/sync_blocks/Cargo.toml index 999b7ec6..5657f754 100644 --- a/node/actors/sync_blocks/Cargo.toml +++ b/node/actors/sync_blocks/Cargo.toml @@ -8,6 +8,7 @@ license.workspace = true [dependencies] anyhow.workspace = true +thiserror.workspace = true tracing.workspace = true concurrency = { path = "../../libs/concurrency" } diff --git a/node/actors/sync_blocks/src/peers/mod.rs b/node/actors/sync_blocks/src/peers/mod.rs index 7eb70009..f81cf469 100644 --- a/node/actors/sync_blocks/src/peers/mod.rs +++ b/node/actors/sync_blocks/src/peers/mod.rs @@ -11,7 +11,7 @@ use concurrency::{ use network::io::{SyncBlocksInputMessage, SyncState}; use roles::{ node, - validator::{BlockNumber, FinalBlock}, + validator::{BlockHeader, BlockNumber, FinalBlock, PayloadHash}, }; use std::{collections::HashMap, sync::Arc}; use storage::WriteBlockStore; @@ -332,25 +332,35 @@ impl PeerStates { Ok(None) } - fn validate_block(&self, block_number: BlockNumber, block: &FinalBlock) -> anyhow::Result<()> { - anyhow::ensure!( - block.header.number == block_number, - "Block does not have requested number" - ); - anyhow::ensure!( - block.payload.hash() == block.header.payload, - "Block payload doesn't match the block header", - ); - anyhow::ensure!( - block.header == block.justification.message.proposal, - "Quorum certificate proposal doesn't match the block header", - ); + fn validate_block( + &self, + block_number: BlockNumber, + block: &FinalBlock, + ) -> Result<(), BlockValidationError> { + if block.header.number != block_number { + return Err(BlockValidationError::NumberMismatch { + requested: block_number, + got: block.header.number, + }); + } + let payload_hash = block.payload.hash(); + if payload_hash != block.header.payload { + return Err(BlockValidationError::HashMismatch { + header_hash: block.header.payload, + payload_hash, + }); + } + if block.header != block.justification.message.proposal { + return Err(BlockValidationError::ProposalMismatch { + block_header: Box::new(block.header), + qc_header: Box::new(block.justification.message.proposal), + }); + } block .justification .verify(&self.config.validator_set, self.config.consensus_threshold) - .context("Failed verifying quorum certificate")?; - Ok(()) + .map_err(BlockValidationError::Justification) } #[instrument(level = "trace", skip(self, ctx))] @@ -369,3 +379,31 @@ impl PeerStates { Ok(()) } } + +/// Errors that can occur validating a `FinalBlock` received from a node. +#[derive(Debug, thiserror::Error)] +enum BlockValidationError { + #[error("block does not have requested number (requested: {requested}, got: {got})")] + NumberMismatch { + requested: BlockNumber, + got: BlockNumber, + }, + #[error( + "block payload doesn't match the block header (hash in header: {header_hash:?}, \ + payload hash: {payload_hash:?})" + )] + HashMismatch { + header_hash: PayloadHash, + payload_hash: PayloadHash, + }, + #[error( + "quorum certificate proposal doesn't match the block header (block header: {block_header:?}, \ + header in QC: {qc_header:?})" + )] + ProposalMismatch { + block_header: Box, + qc_header: Box, + }, + #[error("failed verifying quorum certificate: {0:#?}")] + Justification(#[source] anyhow::Error), +} diff --git a/node/actors/sync_blocks/src/peers/tests.rs b/node/actors/sync_blocks/src/peers/tests.rs index 3b588169..cadbf1f5 100644 --- a/node/actors/sync_blocks/src/peers/tests.rs +++ b/node/actors/sync_blocks/src/peers/tests.rs @@ -860,25 +860,35 @@ async fn processing_invalid_blocks() { let (peer_states, _) = PeerStates::new(message_sender, storage, test_validators.test_config()); let invalid_block = &test_validators.final_blocks[0]; - assert!(peer_states + let err = peer_states .validate_block(BlockNumber(1), invalid_block) - .is_err()); + .unwrap_err(); + assert_matches!( + err, + BlockValidationError::NumberMismatch { + requested: BlockNumber(1), + got: BlockNumber(0), + } + ); let mut invalid_block = test_validators.final_blocks[1].clone(); invalid_block.justification = test_validators.final_blocks[0].justification.clone(); - assert!(peer_states + let err = peer_states .validate_block(BlockNumber(1), &invalid_block) - .is_err()); + .unwrap_err(); + assert_matches!(err, BlockValidationError::ProposalMismatch { .. }); let mut invalid_block = test_validators.final_blocks[1].clone(); invalid_block.payload = validator::Payload(b"invalid".to_vec()); - assert!(peer_states + let err = peer_states .validate_block(BlockNumber(1), &invalid_block) - .is_err()); + .unwrap_err(); + assert_matches!(err, BlockValidationError::HashMismatch { .. }); let other_network = TestValidators::new(4, 2, rng); let invalid_block = &other_network.final_blocks[1]; - assert!(peer_states + let err = peer_states .validate_block(BlockNumber(1), invalid_block) - .is_err()); + .unwrap_err(); + assert_matches!(err, BlockValidationError::Justification(_)); } diff --git a/node/libs/concurrency/src/ctx/channel.rs b/node/libs/concurrency/src/ctx/channel.rs index ee8429cd..fce34f3a 100644 --- a/node/libs/concurrency/src/ctx/channel.rs +++ b/node/libs/concurrency/src/ctx/channel.rs @@ -83,7 +83,7 @@ pub fn unbounded() -> (UnboundedSender, UnboundedReceiver) { } /// Error returned by try_send when channel is full. -#[derive(thiserror::Error, Debug)] +#[derive(Debug, thiserror::Error)] #[error("channel is full")] pub struct FullError; diff --git a/node/libs/concurrency/src/ctx/mod.rs b/node/libs/concurrency/src/ctx/mod.rs index 00b732a0..33718138 100644 --- a/node/libs/concurrency/src/ctx/mod.rs +++ b/node/libs/concurrency/src/ctx/mod.rs @@ -59,16 +59,16 @@ struct Inner { impl Drop for Inner { fn drop(&mut self) { // Automatically cancel the context when State is dropped. - // This wakes the task awaiting parent cancelation, so that it doesn't leak. + // This wakes the task awaiting parent cancellation, so that it doesn't leak. // Note that since children keep a reference to the parent, no - // cascade cancelation will happen here. + // cascade cancellation will happen here. self.canceled.send(); } } /// Error returned when the blocking operation was interrupted /// due to context getting canceled. -#[derive(thiserror::Error, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq, thiserror::Error)] #[error("canceled")] pub struct Canceled; diff --git a/node/libs/concurrency/src/ctx/tests.rs b/node/libs/concurrency/src/ctx/tests.rs index 8bbe53f5..d04622d0 100644 --- a/node/libs/concurrency/src/ctx/tests.rs +++ b/node/libs/concurrency/src/ctx/tests.rs @@ -77,7 +77,7 @@ async fn channel_recv() { recv.recv(ctx).await }) .await; - assert_eq!(Err(Canceled), res); + assert!(matches!(res, Err(Canceled))); } #[tokio::test] diff --git a/node/libs/concurrency/src/scope/task.rs b/node/libs/concurrency/src/scope/task.rs index eb2c3de8..b8f76aaa 100644 --- a/node/libs/concurrency/src/scope/task.rs +++ b/node/libs/concurrency/src/scope/task.rs @@ -46,7 +46,7 @@ use std::{future::Future, sync::Arc}; /// Error returned by `Task::run`/`Task::run_blocking` instead of /// the actual error returned by the task's routine. /// The actual error will be result of the `scope::run!` call. -#[derive(thiserror::Error, Debug)] +#[derive(Debug, thiserror::Error)] #[error("task terminated with an error")] pub(crate) struct Terminated; diff --git a/node/libs/concurrency/src/sync/mod.rs b/node/libs/concurrency/src/sync/mod.rs index a79d6b44..9e920965 100644 --- a/node/libs/concurrency/src/sync/mod.rs +++ b/node/libs/concurrency/src/sync/mod.rs @@ -14,7 +14,7 @@ pub use tokio::{ mod tests; /// Error returned when a channel has been disconnected. -#[derive(thiserror::Error, Debug)] +#[derive(Debug, thiserror::Error)] #[error("disconnected")] pub struct Disconnected; diff --git a/node/libs/crypto/src/bls12_381/mod.rs b/node/libs/crypto/src/bls12_381/mod.rs index 505c48f6..53f9833f 100644 --- a/node/libs/crypto/src/bls12_381/mod.rs +++ b/node/libs/crypto/src/bls12_381/mod.rs @@ -203,7 +203,7 @@ impl Ord for AggregateSignature { } /// Error type for generating and interacting with BLS keys/signatures -#[derive(Debug, thiserror::Error, PartialEq)] +#[derive(Debug, thiserror::Error)] #[non_exhaustive] pub enum Error { /// Signature verification failure diff --git a/node/libs/crypto/src/ed25519/mod.rs b/node/libs/crypto/src/ed25519/mod.rs index 8e7b62b1..f4f11460 100644 --- a/node/libs/crypto/src/ed25519/mod.rs +++ b/node/libs/crypto/src/ed25519/mod.rs @@ -49,8 +49,10 @@ pub struct PublicKey(ed::VerifyingKey); impl PublicKey { /// Verifies a signature of a message against this public key. - pub fn verify(&self, msg: &[u8], sig: &Signature) -> Result<(), ErrInvalidSignature> { - self.0.verify(msg, &sig.0).map_err(|_| ErrInvalidSignature) + pub fn verify(&self, msg: &[u8], sig: &Signature) -> Result<(), InvalidSignatureError> { + self.0 + .verify(msg, &sig.0) + .map_err(|_| InvalidSignatureError) } } @@ -99,6 +101,6 @@ impl ByteFmt for Signature { } /// Error returned when an invalid signature is detected. -#[derive(thiserror::Error, Debug)] +#[derive(Debug, thiserror::Error)] #[error("invalid signature")] -pub struct ErrInvalidSignature; +pub struct InvalidSignatureError; diff --git a/node/libs/roles/src/node/keys.rs b/node/libs/roles/src/node/keys.rs index 2f0683b5..ab58fa4d 100644 --- a/node/libs/roles/src/node/keys.rs +++ b/node/libs/roles/src/node/keys.rs @@ -4,7 +4,7 @@ use super::{Msg, MsgHash, Signed}; use crypto::{ed25519, ByteFmt, Text, TextFmt}; -pub use ed25519::ErrInvalidSignature; +pub use ed25519::InvalidSignatureError; use std::{fmt, sync::Arc}; use utils::enum_util::Variant; @@ -69,7 +69,7 @@ pub struct PublicKey(pub(super) ed25519::PublicKey); impl PublicKey { /// Verify a signed message. - pub fn verify(&self, msg_hash: &MsgHash, sig: &Signature) -> Result<(), ErrInvalidSignature> { + pub fn verify(&self, msg_hash: &MsgHash, sig: &Signature) -> Result<(), InvalidSignatureError> { self.0.verify(&ByteFmt::encode(msg_hash), &sig.0) } } diff --git a/node/libs/roles/src/node/messages.rs b/node/libs/roles/src/node/messages.rs index 233e69c1..18c815d5 100644 --- a/node/libs/roles/src/node/messages.rs +++ b/node/libs/roles/src/node/messages.rs @@ -1,6 +1,6 @@ use crate::node; use crypto::{sha256, ByteFmt, Text, TextFmt}; -use utils::enum_util::{ErrBadVariant, Variant}; +use utils::enum_util::{BadVariantError, Variant}; /// The ID for an authentication session. #[derive(Clone, Debug, PartialEq, Eq)] @@ -25,7 +25,7 @@ impl Variant for SessionId { fn insert(self) -> Msg { Msg::SessionId(self) } - fn extract(msg: Msg) -> Result { + fn extract(msg: Msg) -> Result { let Msg::SessionId(this) = msg; Ok(this) } @@ -45,7 +45,7 @@ pub struct Signed> { impl + Clone> Signed { /// Verify the signature on the message. - pub fn verify(&self) -> Result<(), node::ErrInvalidSignature> { + pub fn verify(&self) -> Result<(), node::InvalidSignatureError> { self.key .verify(&self.msg.clone().insert().hash(), &self.sig) } diff --git a/node/libs/roles/src/validator/messages/consensus.rs b/node/libs/roles/src/validator/messages/consensus.rs index 1af7147f..ec55969f 100644 --- a/node/libs/roles/src/validator/messages/consensus.rs +++ b/node/libs/roles/src/validator/messages/consensus.rs @@ -5,7 +5,7 @@ use crate::validator; use anyhow::{bail, Context}; use bit_vec::BitVec; use std::collections::{BTreeMap, BTreeSet, HashMap}; -use utils::enum_util::{ErrBadVariant, Variant}; +use utils::enum_util::{BadVariantError, Variant}; /// Version of the consensus algorithm that the validator is using. /// It allows to prevent misinterpretation of messages signed by validators @@ -57,9 +57,9 @@ impl Variant for ReplicaPrepare { fn insert(self) -> Msg { ConsensusMsg::ReplicaPrepare(self).insert() } - fn extract(msg: Msg) -> Result { + fn extract(msg: Msg) -> Result { let ConsensusMsg::ReplicaPrepare(this) = Variant::extract(msg)? else { - return Err(ErrBadVariant); + return Err(BadVariantError); }; Ok(this) } @@ -69,9 +69,9 @@ impl Variant for ReplicaCommit { fn insert(self) -> Msg { ConsensusMsg::ReplicaCommit(self).insert() } - fn extract(msg: Msg) -> Result { + fn extract(msg: Msg) -> Result { let ConsensusMsg::ReplicaCommit(this) = Variant::extract(msg)? else { - return Err(ErrBadVariant); + return Err(BadVariantError); }; Ok(this) } @@ -81,9 +81,9 @@ impl Variant for LeaderPrepare { fn insert(self) -> Msg { ConsensusMsg::LeaderPrepare(self).insert() } - fn extract(msg: Msg) -> Result { + fn extract(msg: Msg) -> Result { let ConsensusMsg::LeaderPrepare(this) = Variant::extract(msg)? else { - return Err(ErrBadVariant); + return Err(BadVariantError); }; Ok(this) } @@ -93,9 +93,9 @@ impl Variant for LeaderCommit { fn insert(self) -> Msg { ConsensusMsg::LeaderCommit(self).insert() } - fn extract(msg: Msg) -> Result { + fn extract(msg: Msg) -> Result { let ConsensusMsg::LeaderCommit(this) = Variant::extract(msg)? else { - return Err(ErrBadVariant); + return Err(BadVariantError); }; Ok(this) } diff --git a/node/libs/roles/src/validator/messages/msg.rs b/node/libs/roles/src/validator/messages/msg.rs index 51068c04..c534fd98 100644 --- a/node/libs/roles/src/validator/messages/msg.rs +++ b/node/libs/roles/src/validator/messages/msg.rs @@ -4,7 +4,7 @@ use super::{ConsensusMsg, NetAddress}; use crate::{node::SessionId, validator}; use crypto::{bls12_381::Error, sha256, ByteFmt, Text, TextFmt}; use std::fmt; -use utils::enum_util::{ErrBadVariant, Variant}; +use utils::enum_util::{BadVariantError, Variant}; /// Generic message type for a validator. #[derive(Clone, Debug, PartialEq, Eq)] @@ -28,9 +28,9 @@ impl Variant for ConsensusMsg { fn insert(self) -> Msg { Msg::Consensus(self) } - fn extract(msg: Msg) -> Result { + fn extract(msg: Msg) -> Result { let Msg::Consensus(this) = msg else { - return Err(ErrBadVariant); + return Err(BadVariantError); }; Ok(this) } @@ -40,9 +40,9 @@ impl Variant for SessionId { fn insert(self) -> Msg { Msg::SessionId(self) } - fn extract(msg: Msg) -> Result { + fn extract(msg: Msg) -> Result { let Msg::SessionId(this) = msg else { - return Err(ErrBadVariant); + return Err(BadVariantError); }; Ok(this) } @@ -52,9 +52,9 @@ impl Variant for NetAddress { fn insert(self) -> Msg { Msg::NetAddress(self) } - fn extract(msg: Msg) -> Result { + fn extract(msg: Msg) -> Result { let Msg::NetAddress(this) = msg else { - return Err(ErrBadVariant); + return Err(BadVariantError); }; Ok(this) } @@ -115,7 +115,7 @@ impl + Clone> Signed { impl> Signed { /// Casts a signed message variant to sub/super variant. /// It is an equivalent of constructing/deconstructing enum values. - pub fn cast>(self) -> Result, ErrBadVariant> { + pub fn cast>(self) -> Result, BadVariantError> { Ok(Signed { msg: V2::extract(self.msg.insert())?, key: self.key, diff --git a/node/libs/storage/src/types.rs b/node/libs/storage/src/types.rs index fd39b362..ac4337ac 100644 --- a/node/libs/storage/src/types.rs +++ b/node/libs/storage/src/types.rs @@ -6,7 +6,6 @@ use rocksdb::{Direction, IteratorMode}; use roles::validator::{self, BlockNumber}; use schema::{proto::storage as proto, read_required, required, ProtoFmt}; use std::{iter, ops}; -use thiserror::Error; /// Enum used to represent a key in the database. It also acts as a separator between different stores. #[derive(Clone, Debug, PartialEq, Eq)] @@ -180,7 +179,7 @@ where } /// Storage errors. -#[derive(Debug, Error)] +#[derive(Debug, thiserror::Error)] pub enum StorageError { /// Operation was canceled by structured concurrency framework. #[error("operation was canceled by structured concurrency framework")] diff --git a/node/libs/utils/src/enum_util.rs b/node/libs/utils/src/enum_util.rs index 44a39813..41cc700c 100644 --- a/node/libs/utils/src/enum_util.rs +++ b/node/libs/utils/src/enum_util.rs @@ -2,9 +2,9 @@ //! which is generic over the variants of an enum type. /// Error returned when `Variant::extract` fails. -#[derive(thiserror::Error, Debug)] +#[derive(Debug, thiserror::Error)] #[error("bad enum variant")] -pub struct ErrBadVariant; +pub struct BadVariantError; /// `impl Variant for A` defines an unique embedding of `A` in `E`. /// For example for @@ -61,5 +61,5 @@ pub trait Variant: Sized { /// Constructs an enum value from a value of its variant. fn insert(self) -> Enum; /// Destructs the enum value expecting a particular variant. - fn extract(e: Enum) -> Result; + fn extract(e: Enum) -> Result; }