use ibc_core_client_types::error::ClientError;
use ibc_core_client_types::{Height, Status};
use ibc_core_commitment_types::commitment::{
CommitmentPrefix, CommitmentProofBytes, CommitmentRoot,
};
use ibc_core_host_types::identifiers::{ClientId, ClientType};
use ibc_core_host_types::path::{Path, PathBytes};
use ibc_primitives::prelude::*;
use ibc_primitives::proto::Any;
use ibc_primitives::Timestamp;
use crate::context::{ClientExecutionContext, ClientValidationContext};
use crate::Convertible;
pub trait ClientStateCommon: Convertible<Any> {
fn verify_consensus_state(
&self,
consensus_state: Any,
host_timestamp: &Timestamp,
) -> Result<(), ClientError>;
fn client_type(&self) -> ClientType;
fn latest_height(&self) -> Height;
fn validate_proof_height(&self, proof_height: Height) -> Result<(), ClientError>;
fn verify_upgrade_client(
&self,
upgraded_client_state: Any,
upgraded_consensus_state: Any,
proof_upgrade_client: CommitmentProofBytes,
proof_upgrade_consensus_state: CommitmentProofBytes,
root: &CommitmentRoot,
) -> Result<(), ClientError>;
fn serialize_path(&self, path: Path) -> Result<PathBytes, ClientError>;
fn verify_membership_raw(
&self,
prefix: &CommitmentPrefix,
proof: &CommitmentProofBytes,
root: &CommitmentRoot,
path: PathBytes,
value: Vec<u8>,
) -> Result<(), ClientError>;
fn verify_membership(
&self,
prefix: &CommitmentPrefix,
proof: &CommitmentProofBytes,
root: &CommitmentRoot,
path: Path,
value: Vec<u8>,
) -> Result<(), ClientError> {
let path_bytes = self.serialize_path(path)?;
self.verify_membership_raw(prefix, proof, root, path_bytes, value)
}
fn verify_non_membership_raw(
&self,
prefix: &CommitmentPrefix,
proof: &CommitmentProofBytes,
root: &CommitmentRoot,
path: PathBytes,
) -> Result<(), ClientError>;
fn verify_non_membership(
&self,
prefix: &CommitmentPrefix,
proof: &CommitmentProofBytes,
root: &CommitmentRoot,
path: Path,
) -> Result<(), ClientError> {
let path_bytes = self.serialize_path(path)?;
self.verify_non_membership_raw(prefix, proof, root, path_bytes)
}
}
pub trait ClientStateValidation<V>: ClientStateCommon
where
V: ClientValidationContext,
{
fn verify_client_message(
&self,
ctx: &V,
client_id: &ClientId,
client_message: Any,
) -> Result<(), ClientError>;
fn check_for_misbehaviour(
&self,
ctx: &V,
client_id: &ClientId,
client_message: Any,
) -> Result<bool, ClientError>;
fn status(&self, ctx: &V, client_id: &ClientId) -> Result<Status, ClientError>;
fn check_substitute(&self, ctx: &V, substitute_client_state: Any) -> Result<(), ClientError>;
}
pub trait ClientStateExecution<E>: ClientStateValidation<E>
where
E: ClientExecutionContext,
{
fn initialise(
&self,
ctx: &mut E,
client_id: &ClientId,
consensus_state: Any,
) -> Result<(), ClientError>;
fn update_state(
&self,
ctx: &mut E,
client_id: &ClientId,
header: Any,
) -> Result<Vec<Height>, ClientError>;
fn update_state_on_misbehaviour(
&self,
ctx: &mut E,
client_id: &ClientId,
client_message: Any,
) -> Result<(), ClientError>;
fn update_state_on_upgrade(
&self,
ctx: &mut E,
client_id: &ClientId,
upgraded_client_state: Any,
upgraded_consensus_state: Any,
) -> Result<Height, ClientError>;
fn update_on_recovery(
&self,
ctx: &mut E,
subject_client_id: &ClientId,
substitute_client_state: Any,
substitute_consensus_state: Any,
) -> Result<(), ClientError>;
}
pub trait ClientState<V: ClientValidationContext, E: ClientExecutionContext>:
Send + Sync + ClientStateCommon + ClientStateValidation<V> + ClientStateExecution<E>
{
}
impl<V: ClientValidationContext, E: ClientExecutionContext, T> ClientState<V, E> for T where
T: Send + Sync + ClientStateCommon + ClientStateValidation<V> + ClientStateExecution<E>
{
}