Skip to content

Commit

Permalink
feat(ics008-wasm-client): finalize the api
Browse files Browse the repository at this point in the history
Signed-off-by: aeryz <abdullaheryz@protonmail.com>
  • Loading branch information
aeryz committed Sep 4, 2023
1 parent 4ac6103 commit 29709b2
Show file tree
Hide file tree
Showing 9 changed files with 174 additions and 134 deletions.
116 changes: 75 additions & 41 deletions lib/ics-008-wasm-client/src/ibc_client.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
use core::fmt::Debug;

use cosmwasm_std::{Binary, Deps, DepsMut, Env, MessageInfo};
use unionlabs::{
ibc::core::client::height::Height, TryFromProto, TryFromProtoBytesError, TryFromProtoErrorOf,
ibc::{
core::client::height::Height,
lightclients::wasm::{client_state::ClientState, consensus_state::ConsensusState},
},
Proto, TryFromProto, TryFromProtoBytesError, TryFromProtoErrorOf,
};

use crate::{
Expand All @@ -13,22 +19,30 @@ pub enum StorageState {
Empty,
}

pub trait IBCClient {
type Error: From<TryFromProtoBytesError<TryFromProtoErrorOf<Self::Header>>>
+ From<TryFromProtoBytesError<TryFromProtoErrorOf<Self::Misbehaviour>>>
+ From<Error>;
pub trait IbcClient {
type Error: From<TryFromProtoBytesError<TryFromProtoErrorOf<Self::Header>>> + From<Error>;
type CustomQuery: cosmwasm_std::CustomQuery;
// TODO(aeryz): see #583
type Header: TryFromProto;
type Misbehaviour: TryFromProto;
type ClientState;
type ConsensusState;
// TODO(aeryz): see #583, #588
type Misbehaviour;
type ClientState: TryFromProto;
type ConsensusState: TryFromProto;

fn execute(
deps: DepsMut<Self::CustomQuery>,
env: Env,
_info: MessageInfo,
msg: ExecuteMsg,
) -> Result<ContractResult, Self::Error> {
) -> Result<ContractResult, Self::Error>
where
// NOTE(aeryz): unfortunately bounding to `Debug` in associated type creates a
// recursion in the compiler, see this issue: https://github.com/rust-lang/rust/issues/87755
<Self::ClientState as Proto>::Proto: prost::Message + Default,
TryFromProtoErrorOf<Self::ClientState>: Debug,
<Self::ConsensusState as Proto>::Proto: prost::Message + Default,
TryFromProtoErrorOf<Self::ConsensusState>: Debug,
{
match msg {
ExecuteMsg::VerifyMembership {
height,
Expand Down Expand Up @@ -61,39 +75,54 @@ pub trait IBCClient {
path,
StorageState::Empty,
),
ExecuteMsg::VerifyClientMessage {
client_message:
ClientMessage {
header,
misbehaviour,
},
} => {
if let Some(header) = header {
ExecuteMsg::VerifyClientMessage { client_message } => match client_message {
ClientMessage::Header(header) => {
let header = Self::Header::try_from_proto_bytes(&header.data)?;
Self::verify_header(deps.as_ref(), env, header)
} else if let Some(misbehaviour) = misbehaviour {
let misbehaviour =
Self::Misbehaviour::try_from_proto_bytes(&misbehaviour.data)?;
Self::verify_misbehaviour(deps.as_ref(), misbehaviour)
} else {
// Note(aeryz): Host implementation doesn't count this as error
Ok(ContractResult::valid(None))
}
}
ExecuteMsg::UpdateState {
client_message: ClientMessage { header, .. },
} => {
if let Some(header) = header {
ClientMessage::Misbehaviour(_misbehaviour) => {
Ok(ContractResult::invalid("Not implemented".to_string()))
}
},
ExecuteMsg::UpdateState { client_message } => match client_message {
ClientMessage::Header(header) => {
let header = Self::Header::try_from_proto_bytes(&header.data)?;
Self::update_state(deps, env, header)
} else {
Err(Error::NotSpecCompliant(
"`UpdateState` is not valid for misbehaviour".to_string(),
)
.into())
}
ClientMessage::Misbehaviour(_) => Err(Error::UnexpectedCallDataFromHostModule(
"`UpdateState` cannot be called with `Misbehaviour`".to_string(),
)
.into()),
},
ExecuteMsg::UpdateStateOnMisbehaviour { client_message } => {
Self::update_state_on_misbehaviour(deps, client_message)
}
ExecuteMsg::CheckForMisbehaviour { client_message } => match client_message {
ClientMessage::Header(header) => {
let header = Self::Header::try_from_proto_bytes(&header.data)?;
Self::verify_header(deps.as_ref(), env, header)
}
ClientMessage::Misbehaviour(_) => {
Ok(ContractResult::invalid("Not implemented".to_string()))
}
},
ExecuteMsg::VerifyUpgradeAndUpdateState {
upgrade_client_state,
upgrade_consensus_state,
proof_upgrade_client,
proof_upgrade_consensus_state,
} => Self::verify_upgrade_and_update_state(
deps,
<_>::try_from_proto(upgrade_client_state)
.map_err(|err| Error::Decode(format!("{err:?}")))?,
<_>::try_from_proto(upgrade_consensus_state)
.map_err(|err| Error::Decode(format!("{err:?}")))?,
proof_upgrade_client,
proof_upgrade_consensus_state,
),
ExecuteMsg::CheckSubstituteAndUpdateState {} => {
Self::check_substitute_and_update_state(deps.as_ref())
}
_ => Ok(ContractResult::valid(None)),
}
}

Expand Down Expand Up @@ -138,19 +167,24 @@ pub trait IBCClient {

// TODO(aeryz): make this client message generic over the underlying types
fn update_state_on_misbehaviour(
deps: Deps<Self::CustomQuery>,
deps: DepsMut<Self::CustomQuery>,
client_message: ClientMessage,
) -> Result<ContractResult, Self::Error>;

fn check_for_misbehaviour(
fn check_for_misbehaviour_on_header(
deps: Deps<Self::CustomQuery>,
client_message: ClientMessage,
header: Self::Header,
) -> Result<ContractResult, Self::Error>;

fn verify_upgrade_and_update_state(
fn check_for_misbehaviour_on_misbehaviour(
deps: Deps<Self::CustomQuery>,
upgrade_client_state: Self::ClientState,
upgrade_consensus_state: Self::ConsensusState,
misbehaviour: Self::Misbehaviour,
) -> Result<ContractResult, Self::Error>;

fn verify_upgrade_and_update_state(
deps: DepsMut<Self::CustomQuery>,
upgrade_client_state: ClientState<Self::ClientState>,
upgrade_consensus_state: ConsensusState<Self::ConsensusState>,
proof_upgrade_client: Binary,
proof_upgrade_consensus_state: Binary,
) -> Result<ContractResult, Self::Error>;
Expand Down
10 changes: 3 additions & 7 deletions lib/ics-008-wasm-client/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![recursion_limit = "512"]

mod ibc_client;
mod msg;
pub mod storage_utils;
Expand All @@ -8,12 +10,6 @@ pub use msg::*;
#[derive(Debug)]
pub enum Error {
Decode(String),
NotSpecCompliant(String),
UnexpectedCallDataFromHostModule(String),
ClientStateNotFound,
}

impl Error {
pub fn decode<S: Into<String>>(msg: S) -> Error {
Error::Decode(msg.into())
}
}
8 changes: 3 additions & 5 deletions lib/ics-008-wasm-client/src/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ pub struct MerklePath {
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub struct ClientMessage {
pub header: Option<Header>,
pub misbehaviour: Option<Misbehaviour>,
pub enum ClientMessage {
Header(Header),
Misbehaviour(Misbehaviour),
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
Expand Down Expand Up @@ -96,8 +96,6 @@ pub enum ExecuteMsg {
},

CheckSubstituteAndUpdateState {},

ExportMetadata {},
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
Expand Down
32 changes: 20 additions & 12 deletions light-clients/cometbls-light-client/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use ics008_wasm_client::{
storage_utils::{
read_client_state, read_consensus_state, save_client_state, save_consensus_state,
},
ContractResult, IBCClient, MerklePath, Status, StorageState,
ContractResult, IbcClient, MerklePath, Status, StorageState,
};
use prost::Message;
use unionlabs::{
Expand All @@ -25,15 +25,15 @@ type WasmConsensusState =

pub struct CometblsLightClient;

impl IBCClient for CometblsLightClient {
impl IbcClient for CometblsLightClient {
type Error = Error;

type CustomQuery = Empty;

type Header = Header;

// TODO(aeryz): Change this to appropriate misbehavior type when it is implemented
type Misbehaviour = Header;
type Misbehaviour = ();

type ClientState = ClientState;

Expand Down Expand Up @@ -196,33 +196,41 @@ impl IBCClient for CometblsLightClient {
}

fn update_state_on_misbehaviour(
_deps: Deps<Self::CustomQuery>,
_deps: DepsMut<Self::CustomQuery>,
_client_message: ics008_wasm_client::ClientMessage,
) -> Result<ContractResult, Self::Error> {
Ok(ContractResult::valid(None))
Ok(ContractResult::invalid("Not implemented".to_string()))
}

fn check_for_misbehaviour(
fn check_for_misbehaviour_on_header(
_deps: Deps<Self::CustomQuery>,
_client_message: ics008_wasm_client::ClientMessage,
_header: Self::Header,
) -> Result<ContractResult, Self::Error> {
// TODO(aeryz): Leaving this as success for us to be able to update the client. See: #588.
Ok(ContractResult::valid(None))
}

fn verify_upgrade_and_update_state(
fn check_for_misbehaviour_on_misbehaviour(
_deps: Deps<Self::CustomQuery>,
_upgrade_client_state: Self::ClientState,
_upgrade_consensus_state: Self::ConsensusState,
_misbehaviour: Self::Misbehaviour,
) -> Result<ContractResult, Self::Error> {
Ok(ContractResult::invalid("Not implemented".to_string()))
}

fn verify_upgrade_and_update_state(
_deps: DepsMut<Self::CustomQuery>,
_upgrade_client_state: WasmClientState,
_upgrade_consensus_state: WasmConsensusState,
_proof_upgrade_client: Binary,
_proof_upgrade_consensus_state: Binary,
) -> Result<ContractResult, Self::Error> {
Ok(ContractResult::valid(None))
Ok(ContractResult::invalid("Not implemented".to_string()))
}

fn check_substitute_and_update_state(
_deps: Deps<Self::CustomQuery>,
) -> Result<ContractResult, Self::Error> {
Ok(ContractResult::valid(None))
Ok(ContractResult::invalid("Not implemented".to_string()))
}

fn status(
Expand Down
4 changes: 3 additions & 1 deletion light-clients/cometbls-light-client/src/contract.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
use cosmwasm_std::{
entry_point, to_binary, Deps, DepsMut, Env, MessageInfo, QueryResponse, Response,
};
use ics008_wasm_client::{ExecuteMsg, IBCClient, QueryMsg};
use ics008_wasm_client::{ExecuteMsg, IbcClient, QueryMsg};
use serde::{Deserialize, Serialize};

use crate::{client::CometblsLightClient, errors::Error};

#[derive(Debug, Serialize, Deserialize)]
pub struct InstantiateMsg {}

#[entry_point]
Expand Down
2 changes: 1 addition & 1 deletion light-clients/cometbls-light-client/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ impl From<ics008_wasm_client::Error> for Error {
fn from(error: ics008_wasm_client::Error) -> Self {
match error {
ics008_wasm_client::Error::Decode(e) => Error::DecodeError(e),
ics008_wasm_client::Error::NotSpecCompliant(e) => Error::Wasm(e),
ics008_wasm_client::Error::UnexpectedCallDataFromHostModule(e) => Error::Wasm(e),
ics008_wasm_client::Error::ClientStateNotFound => Error::Wasm(format!("{error:#?}")),
}
}
Expand Down
Loading

0 comments on commit 29709b2

Please sign in to comment.