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
use core::fmt::{Debug, Display, Formatter};
use core::str::FromStr;
use ibc_primitives::prelude::*;
use crate::error::ClientError;
/// `UpdateKind` represents the 2 ways that a client can be updated
/// in IBC: either through a `MsgUpdateClient`, or a `MsgSubmitMisbehaviour`.
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum UpdateKind {
/// this is the typical scenario where a new header is submitted to the client
/// to update the client. Note that light clients are free to define the type
/// of the object used to update them (e.g. could be a list of headers).
UpdateClient,
/// this is the scenario where misbehaviour is submitted to the client
/// (e.g 2 headers with the same height in Tendermint)
SubmitMisbehaviour,
}
/// Represents the status of a client
#[derive(Clone, Debug, PartialEq, Eq, Copy)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
pub enum Status {
/// The client is active and allowed to be used
Active,
/// The client is frozen and not allowed to be used
Frozen,
/// The client is expired and not allowed to be used
Expired,
/// Unauthorized indicates that the client type is not registered as an allowed client type.
Unauthorized,
}
impl Status {
pub fn is_active(&self) -> bool {
*self == Status::Active
}
pub fn is_frozen(&self) -> bool {
*self == Status::Frozen
}
pub fn is_expired(&self) -> bool {
*self == Status::Expired
}
/// Checks whether the status is active; returns `Err` if not.
pub fn verify_is_active(&self) -> Result<(), ClientError> {
match self {
Self::Active => Ok(()),
&status => Err(ClientError::ClientNotActive { status }),
}
}
/// Checks whether the client is either frozen or expired; returns `Err` if not.
pub fn verify_is_inactive(&self) -> Result<(), ClientError> {
match self {
Self::Frozen | Self::Expired => Ok(()),
&status => Err(ClientError::ClientNotInactive { status }),
}
}
}
impl Display for Status {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
write!(f, "{self:?}")
}
}
impl FromStr for Status {
type Err = ClientError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"ACTIVE" => Ok(Status::Active),
"FROZEN" => Ok(Status::Frozen),
"EXPIRED" => Ok(Status::Expired),
"UNAUTHORIZED" => Ok(Status::Unauthorized),
_ => Err(ClientError::Other {
description: format!("invalid status string: {s}"),
}),
}
}
}