1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
//! Defines the client error type
use core::convert::Infallible;
use displaydoc::Display;
use ibc_core_commitment_types::error::CommitmentError;
use ibc_core_host_types::error::IdentifierError;
use ibc_core_host_types::identifiers::{ClientId, ClientType};
use ibc_primitives::prelude::*;
use ibc_primitives::Timestamp;
use super::status::Status;
use crate::height::Height;
/// Encodes all the possible client errors
#[derive(Debug, Display)]
pub enum ClientError {
/// upgrade client error: `{0}`
Upgrade(UpgradeClientError),
/// client is frozen with description: `{description}`
ClientFrozen { description: String },
/// client is not active. Status=`{status}`
ClientNotActive { status: Status },
/// client is not frozen or expired. Status=`{status}`
ClientNotInactive { status: Status },
/// client state not found: `{client_id}`
ClientStateNotFound { client_id: ClientId },
/// client state already exists: `{client_id}`
ClientStateAlreadyExists { client_id: ClientId },
/// Substitute client height `{substitute_height}` is not greater than subject client height `{subject_height}` during client recovery
ClientRecoveryHeightMismatch {
subject_height: Height,
substitute_height: Height,
},
/// Subject and substitute client state mismatch during client recovery
ClientRecoveryStateMismatch,
/// consensus state not found at: `{client_id}` at height `{height}`
ConsensusStateNotFound { client_id: ClientId, height: Height },
/// Processed time or height for the client `{client_id}` at height `{height}` not found
UpdateMetaDataNotFound { client_id: ClientId, height: Height },
/// header verification failed with reason: `{reason}`
HeaderVerificationFailure { reason: String },
/// failed to build trust threshold from fraction: `{numerator}`/`{denominator}`
InvalidTrustThreshold { numerator: u64, denominator: u64 },
/// failed to build Tendermint domain type trust threshold from fraction: `{numerator}`/`{denominator}`
FailedTrustThresholdConversion { numerator: u64, denominator: u64 },
/// unknown client state type: `{client_state_type}`
UnknownClientStateType { client_state_type: String },
/// unknown client consensus state type: `{consensus_state_type}`
UnknownConsensusStateType { consensus_state_type: String },
/// unknown header type: `{header_type}`
UnknownHeaderType { header_type: String },
/// unknown misbehaviour type: `{misbehaviour_type}`
UnknownMisbehaviourType { misbehaviour_type: String },
/// missing raw client state
MissingRawClientState,
/// missing raw client consensus state
MissingRawConsensusState,
/// invalid client id in the update client message: `{0}`
InvalidMsgUpdateClientId(IdentifierError),
/// invalid client id in recover client message: `{0}`
InvalidMsgRecoverClientId(IdentifierError),
/// invalid client identifier error: `{0}`
InvalidClientIdentifier(IdentifierError),
/// invalid raw header error: `{reason}`
InvalidRawHeader { reason: String },
/// missing raw client message
MissingClientMessage,
/// invalid raw misbehaviour error: `{0}`
InvalidRawMisbehaviour(IdentifierError),
/// missing raw misbehaviour
MissingRawMisbehaviour,
/// revision height cannot be zero
InvalidHeight,
/// height cannot end up zero or negative
InvalidHeightResult,
/// the proof height is insufficient: latest_height=`{latest_height}` proof_height=`{proof_height}`
InvalidProofHeight {
latest_height: Height,
proof_height: Height,
},
/// invalid commitment proof bytes error: `{0}`
InvalidCommitmentProof(CommitmentError),
/// mismatch between client and arguments types
ClientArgsTypeMismatch { client_type: ClientType },
/// timestamp is invalid or missing, timestamp=`{time1}`, now=`{time2}`
InvalidConsensusStateTimestamp { time1: Timestamp, time2: Timestamp },
/// the local consensus state could not be retrieved for height `{height}`
MissingLocalConsensusState { height: Height },
/// invalid signer error: `{reason}`
InvalidSigner { reason: String },
/// ics23 verification failure error: `{0}`
Ics23Verification(CommitmentError),
/// misbehaviour handling failed with reason: `{reason}`
MisbehaviourHandlingFailure { reason: String },
/// client-specific error: `{description}`
ClientSpecific { description: String },
/// client counter overflow error
CounterOverflow,
/// update client message did not contain valid header or misbehaviour
InvalidUpdateClientMessage,
/// other error: `{description}`
Other { description: String },
/// invalid attribute key: `{attribute_key}`
InvalidAttributeKey { attribute_key: String },
/// invalid attribute value: `{attribute_value}`
InvalidAttributeValue { attribute_value: String },
/// Missing attribute key: `{attribute_key}`
MissingAttributeKey { attribute_key: String },
}
impl From<&'static str> for ClientError {
fn from(s: &'static str) -> Self {
Self::Other {
description: s.to_string(),
}
}
}
impl From<Infallible> for ClientError {
fn from(value: Infallible) -> Self {
match value {}
}
}
#[cfg(feature = "std")]
impl std::error::Error for ClientError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match &self {
Self::InvalidMsgUpdateClientId(e)
| Self::InvalidClientIdentifier(e)
| Self::InvalidRawMisbehaviour(e) => Some(e),
Self::InvalidCommitmentProof(e) | Self::Ics23Verification(e) => Some(e),
_ => None,
}
}
}
/// Encodes all the possible upgrade client errors
#[derive(Debug, Display)]
pub enum UpgradeClientError {
/// invalid proof for the upgraded client state error: `{0}`
InvalidUpgradeClientProof(CommitmentError),
/// invalid proof for the upgraded consensus state error: `{0}`
InvalidUpgradeConsensusStateProof(CommitmentError),
/// upgraded client height `{upgraded_height}` must be at greater than current client height `{client_height}`
LowUpgradeHeight {
upgraded_height: Height,
client_height: Height,
},
/// Invalid upgrade path: `{reason}`
InvalidUpgradePath { reason: String },
/// invalid upgrade proposal: `{reason}`
InvalidUpgradeProposal { reason: String },
/// invalid upgrade plan: `{reason}`
InvalidUpgradePlan { reason: String },
/// other upgrade client error: `{reason}`
Other { reason: String },
}
impl From<UpgradeClientError> for ClientError {
fn from(e: UpgradeClientError) -> Self {
ClientError::Upgrade(e)
}
}
#[cfg(feature = "std")]
impl std::error::Error for UpgradeClientError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match &self {
Self::InvalidUpgradeClientProof(e) | Self::InvalidUpgradeConsensusStateProof(e) => {
Some(e)
}
_ => None,
}
}
}