use shared_ids::{ClientId, ReplicaId};
use usig::{Count, UsigError};
use crate::View;
#[derive(thiserror::Error, Debug)]
pub(super) enum InnerError {
#[error("replica {receiver:?} received Commit sent by the primary {primary:?}")]
CommitFromPrimary {
receiver: ReplicaId,
primary: ReplicaId,
},
#[error("replica {receiver:?} received Prepare sent by backup {backup:?} for view {view:?}")]
PrepareFromBackup {
receiver: ReplicaId,
backup: ReplicaId,
view: View,
},
#[error("replica's {receiver:?} validation of Prepare from {origin:?} failed since it contains an invalid client request")]
RequestInPrepare {
receiver: ReplicaId,
origin: ReplicaId,
},
#[error("replica's ({receiver:?}) validation of the checkpoint certificate from {origin:?} failed since it does not contain at least t + 1 messages")]
CheckpointCertNotSufficientMsgs {
receiver: ReplicaId,
origin: ReplicaId,
},
#[error("replica's ({receiver:?}) validation of the checkpoint certificate from {origin:?} failed since not all checkpoint messages have the same state hash")]
CheckpointCertNotAllSameStateHash {
receiver: ReplicaId,
origin: ReplicaId,
},
#[error("replica's ({receiver:?}) validation of the checkpoint certificate from {origin:?} failed since not all checkpoint messages agree on the same counter of the latest accepted Prepare")]
CheckpointCertNotAllSameLatestPrep {
receiver: ReplicaId,
origin: ReplicaId,
},
#[error("replica's ({receiver:?}) validation of the checkpoint certificate from {origin:?} failed since not all checkpoint messages originate from a different replica")]
CheckpointCertNotAllDifferentOrigin {
receiver: ReplicaId,
origin: ReplicaId,
},
#[error("replica's ({receiver:?}) validation of the new-view's checkpoint certificate failed since it does not contain at least t + 1 view-change messages")]
NewViewCheckpointCertNotSufficientMsgs { receiver: ReplicaId },
#[error("replica's ({receiver:?}) validation of the new-view's checkpoint certificate failed since not all view-change messages are for the same next-view")]
NewViewCheckpointCertNotAllSameNextView { receiver: ReplicaId },
#[error("replica's ({receiver:?}) validation of the new-view's checkpoint certificate failed since not all view-change messages originate from a different replica")]
NewViewCheckpointCertNotAllDifferentOrigin { receiver: ReplicaId },
#[error("replica's {receiver:?} validation of the new-view message failed since the origin of the new-view message is {origin_actual:?} when it should be the expected next view ({origin_expected:?})")]
NewViewContentUnexpectedNextView {
receiver: ReplicaId,
origin_actual: ReplicaId,
origin_expected: ReplicaId,
},
#[error(
"replica {replica:?} validation of the message of type {msg_type:?} from {origin:?} failed since the usig is invalid: {usig_error:?}"
)]
Usig {
usig_error: UsigError,
replica: ReplicaId,
msg_type: &'static str,
origin: ReplicaId,
},
#[error("replica's ({receiver:?}) validation of the view-change message from {origin:?} failed since there are holes in the sequence number of messages in its log")]
ViewChangeHolesInMessageLog {
receiver: ReplicaId,
origin: ReplicaId,
},
#[error("replica's ({receiver:?}) validation of the view-change message from {origin:?} failed since the message log
is empty when a certificate is passed: First message is expected to be the
checkpoint of the replica")]
ViewChangeMessageLogEmptyWithCert {
receiver: ReplicaId,
origin: ReplicaId,
},
#[error("replica's ({receiver:?}) validation of the view-change message from {origin:?} failed since the counter of its first message is {counter_first_msg:?} when it should be {counter_expected:?}")]
ViewChangeFirstUnexpectedCounter {
receiver: ReplicaId,
origin: ReplicaId,
counter_first_msg: Count,
counter_expected: Count,
},
#[error("replica's ({receiver:?}) validation of the view-change message from {origin:?} failed since the counter of its last message is {counter_last_msg:?} when it should be {counter_expected:?}")]
ViewChangeLastUnexpectedCounter {
receiver: ReplicaId,
origin: ReplicaId,
counter_last_msg: Count,
counter_expected: Count,
},
#[error("replica's ({receiver:?}) validation of the view-change message from {origin:?} failed since its log is empty when it should not be the case")]
ViewChangeLogUnexpectedlyEmpty {
receiver: ReplicaId,
origin: ReplicaId,
},
#[error("replica's ({receiver:?}) validation of the request for view-change from {origin:?} failed since the previous view must be smaller than the next view")]
ReqViewChangeIncompatiblePrevNextView {
receiver: ReplicaId,
origin: ReplicaId,
},
}
impl InnerError {
pub(crate) fn parse_usig_error(
usig_error: UsigError,
replica: ReplicaId,
msg_type: &'static str,
origin: ReplicaId,
) -> Self {
Self::Usig {
usig_error,
replica,
msg_type,
origin,
}
}
}
#[derive(thiserror::Error, Debug)]
pub enum Error {
#[error("replica's ({receiver:?}) validation of Commit from {origin:?} failed")]
Commit {
receiver: ReplicaId,
origin: ReplicaId,
},
#[error("replica's ({receiver:?}) validation of Prepare from {origin:?} failed")]
Prepare {
receiver: ReplicaId,
origin: ReplicaId,
},
#[error(
"replica's ({receiver:?}) validation of the checkpoint certificate from {origin:?} failed"
)]
CheckpointCert {
receiver: ReplicaId,
origin: ReplicaId,
},
#[error("replica's ({receiver:?}) validation of the new-view checkpoint cert failed")]
NewViewCheckpointCert { receiver: ReplicaId },
#[error("replica's ({receiver:?}) validation of the new-view message from {origin:?} failed")]
NewView {
receiver: ReplicaId,
origin: ReplicaId,
},
#[error(
"replica's ({receiver:?}) validation of the view-change message from {origin:?} failed"
)]
ViewChange {
receiver: ReplicaId,
origin: ReplicaId,
},
#[error("replica's ({receiver:?}) validation of the request for a view-change from {origin:?} failed")]
ReqViewChange {
receiver: ReplicaId,
origin: ReplicaId,
},
#[error("replica's ({receiver:?}) validation of the attestation from {origin:?} failed")]
Attestation {
receiver: ReplicaId,
origin: ReplicaId,
},
#[error("replica's ({receiver:?}) validation of the request from {client_id:?} failed")]
Request {
receiver: ReplicaId,
client_id: ClientId,
},
#[error(
"replica {replica:?} could not perform the desired usig operation for message of type {msg_type:?} as the usig is invalid: {usig_error:?}"
)]
Usig {
replica: ReplicaId,
msg_type: &'static str,
usig_error: UsigError,
},
}
impl From<InnerError> for Error {
fn from(inner: InnerError) -> Self {
match inner {
InnerError::CommitFromPrimary { receiver, primary } => Error::Commit {
receiver,
origin: primary,
},
InnerError::PrepareFromBackup {
receiver,
backup,
view: _,
} => Error::Prepare {
receiver,
origin: backup,
},
InnerError::RequestInPrepare { receiver, origin } => {
Error::Prepare { receiver, origin }
}
InnerError::CheckpointCertNotSufficientMsgs { receiver, origin } => {
Error::CheckpointCert { receiver, origin }
}
InnerError::CheckpointCertNotAllSameStateHash { receiver, origin } => {
Error::CheckpointCert { receiver, origin }
}
InnerError::CheckpointCertNotAllSameLatestPrep { receiver, origin } => {
Error::CheckpointCert { receiver, origin }
}
InnerError::CheckpointCertNotAllDifferentOrigin { receiver, origin } => {
Error::CheckpointCert { receiver, origin }
}
InnerError::NewViewCheckpointCertNotSufficientMsgs { receiver } => {
Error::NewViewCheckpointCert { receiver }
}
InnerError::NewViewCheckpointCertNotAllSameNextView { receiver } => {
Error::NewViewCheckpointCert { receiver }
}
InnerError::NewViewCheckpointCertNotAllDifferentOrigin { receiver } => {
Error::NewViewCheckpointCert { receiver }
}
InnerError::NewViewContentUnexpectedNextView {
receiver,
origin_actual,
origin_expected: _,
} => Error::NewView {
receiver,
origin: origin_actual,
},
InnerError::ViewChangeHolesInMessageLog { receiver, origin } => {
Error::ViewChange { receiver, origin }
}
InnerError::ViewChangeMessageLogEmptyWithCert { receiver, origin } => {
Error::ViewChange { receiver, origin }
}
InnerError::ViewChangeFirstUnexpectedCounter {
receiver,
origin,
counter_first_msg: _,
counter_expected: _,
} => Error::ViewChange { receiver, origin },
InnerError::ViewChangeLastUnexpectedCounter {
receiver,
origin,
counter_last_msg: _,
counter_expected: _,
} => Error::ViewChange { receiver, origin },
InnerError::ViewChangeLogUnexpectedlyEmpty { receiver, origin } => {
Error::ViewChange { receiver, origin }
}
InnerError::ReqViewChangeIncompatiblePrevNextView { receiver, origin } => {
Error::ReqViewChange { receiver, origin }
}
InnerError::Usig {
usig_error,
replica,
msg_type,
origin: _,
} => Error::Usig {
replica,
msg_type,
usig_error,
},
}
}
}