Skip to content

Commit

Permalink
add dummy client
Browse files Browse the repository at this point in the history
  • Loading branch information
rnbguy committed Jul 23, 2024
1 parent 4a080b5 commit 9ce305a
Show file tree
Hide file tree
Showing 15 changed files with 482 additions and 1 deletion.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
.DS_Store
corelib/
target/
**/Cargo.lock

# vscode
.vscode/
.vscode/
18 changes: 18 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
resolver = "2"
members = [
"light-client/*",
"dummy-light-client/*",
]

[workspace.package]
Expand Down
9 changes: 9 additions & 0 deletions dummy-light-client/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<div align="center">
<h1>Dummy Light Client</h1>
</div>

A light client without any validation. Its purpose is to bootstrap IBC without
having a full light client implementation.

> [!WARNING]\
> This light client is not secure and should not be used in production.
30 changes: 30 additions & 0 deletions dummy-light-client/cw-contract/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
[package]
name = "ibc-client-dummy-cw"
authors = { workspace = true }
edition = { workspace = true }
license = { workspace = true }
repository = { workspace = true }
rust-version = { workspace = true }
version = { workspace = true }
readme = "./../README.md"
keywords = [ "dummy", "ibc", "light-client", "CosmWasm" ]
description = "CosmWasm contract for dummy IBC client."

[lib]
crate-type = [ "cdylib", "rlib" ]

[dependencies]
# ibc dependencies
ibc-core = { workspace = true }
ibc-client-cw = { workspace = true }
ibc-client-dummy = { path = "./../impls" }

# cosmwasm dependencies
cosmwasm-std = "2.1.0"

[features]
default = [ "std" ]
std = [
"ibc-core/std",
"ibc-client-cw/std",
]
9 changes: 9 additions & 0 deletions dummy-light-client/cw-contract/src/client_type.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use ibc_client_cw::api::ClientType;
use ibc_client_dummy::{ClientState, ConsensusState};

pub struct DummyLightClient;

impl<'a> ClientType<'a> for DummyLightClient {
type ClientState = ClientState;
type ConsensusState = ConsensusState;
}
37 changes: 37 additions & 0 deletions dummy-light-client/cw-contract/src/entrypoint.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use cosmwasm_std::{entry_point, Binary, Deps, DepsMut, Env, MessageInfo, Response};
use ibc_client_cw::context::Context;
use ibc_client_cw::types::{ContractError, InstantiateMsg, QueryMsg, SudoMsg};

use crate::client_type::DummyLightClient;

pub type DummyLightClientContext<'a> = Context<'a, DummyLightClient>;

#[entry_point]
pub fn instantiate(
deps: DepsMut<'_>,
env: Env,
_info: MessageInfo,
msg: InstantiateMsg,
) -> Result<Response, ContractError> {
let mut ctx = DummyLightClientContext::new_mut(deps, env)?;

let data = ctx.instantiate(msg)?;

Ok(Response::default().set_data(data))
}

#[entry_point]
pub fn sudo(deps: DepsMut<'_>, env: Env, msg: SudoMsg) -> Result<Response, ContractError> {
let mut ctx = DummyLightClientContext::new_mut(deps, env)?;

let data = ctx.sudo(msg)?;

Ok(Response::default().set_data(data))
}

#[entry_point]
pub fn query(deps: Deps<'_>, env: Env, msg: QueryMsg) -> Result<Binary, ContractError> {
let ctx = DummyLightClientContext::new_ref(deps, env)?;

ctx.query(msg)
}
2 changes: 2 additions & 0 deletions dummy-light-client/cw-contract/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod client_type;
pub mod entrypoint;
27 changes: 27 additions & 0 deletions dummy-light-client/impls/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[package]
name = "ibc-client-dummy"
authors = { workspace = true }
edition = { workspace = true }
license = { workspace = true }
rust-version = { workspace = true }
version = { workspace = true }
repository = { workspace = true }
readme = "./../README.md"
keywords = [ "dummy", "test", "ibc", "light-client" ]
description = "A light client without any validation. Only for testing."

[lints]
workspace = true

[dependencies]
# external dependencies
derive_more = { workspace = true }

# ibc dependencies
ibc-core = { workspace = true }

[features]
default = [ "std" ]
std = [
"ibc-core/std",
]
65 changes: 65 additions & 0 deletions dummy-light-client/impls/src/client_state/common.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
use ibc_core::client::context::client_state::ClientStateCommon;
use ibc_core::client::types::error::ClientError;
use ibc_core::client::types::Height;
use ibc_core::commitment_types::commitment::{
CommitmentPrefix, CommitmentProofBytes, CommitmentRoot,
};
use ibc_core::host::types::identifiers::ClientType;
use ibc_core::host::types::path::{Path, PathBytes};
use ibc_core::primitives::proto::Any;

use super::ClientState;

impl ClientStateCommon for ClientState {
fn verify_consensus_state(&self, consensus_state: Any) -> Result<(), ClientError> {
Ok(())
}

fn client_type(&self) -> ClientType {
"blind-001".parse().unwrap()
}

fn latest_height(&self) -> Height {
self.latest_height
}

fn validate_proof_height(&self, proof_height: Height) -> Result<(), ClientError> {
Ok(())
}

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> {
Ok(())
}

fn serialize_path(&self, path: Path) -> Result<PathBytes, ClientError> {
Ok(path.to_string().as_bytes().to_vec().into())
}

fn verify_membership_raw(
&self,
prefix: &CommitmentPrefix,
proof: &CommitmentProofBytes,
root: &CommitmentRoot,
path: PathBytes,
value: Vec<u8>,
) -> Result<(), ClientError> {
Ok(())
}

fn verify_non_membership_raw(
&self,
prefix: &CommitmentPrefix,
proof: &CommitmentProofBytes,
root: &CommitmentRoot,
path: PathBytes,
) -> Result<(), ClientError> {
Ok(())
}
}
140 changes: 140 additions & 0 deletions dummy-light-client/impls/src/client_state/execution.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
use ibc_core::client::context::client_state::ClientStateExecution;
use ibc_core::client::context::prelude::ClientStateCommon;
use ibc_core::client::context::ClientExecutionContext;
use ibc_core::client::types::error::ClientError;
use ibc_core::client::types::Height;
use ibc_core::host::types::identifiers::ClientId;
use ibc_core::host::types::path::{ClientConsensusStatePath, ClientStatePath};
use ibc_core::primitives::proto::Any;
use ibc_core::primitives::Timestamp;

use crate::ConsensusState;

use super::ClientState;

impl<E> ClientStateExecution<E> for ClientState
where
E: ClientExecutionContext<ClientStateMut = ClientState, ConsensusStateRef = ConsensusState>,
{
fn initialise(
&self,
ctx: &mut E,
client_id: &ClientId,
consensus_state: Any,
) -> Result<(), ClientError> {
let latest_height = Height::min(0);

update_client_and_consensus_state(
ctx,
latest_height,
client_id,
self.clone(),
consensus_state.try_into()?,
)?;

Ok(())
}

fn update_state(
&self,
ctx: &mut E,
client_id: &ClientId,
header: Any,
) -> Result<Vec<Height>, ClientError> {
let latest_height = ctx.client_state(client_id)?.latest_height().increment();

let new_client_state = ClientState { latest_height };

update_client_and_consensus_state(
ctx,
latest_height,
client_id,
new_client_state,
ConsensusState::default(),
)?;

Ok(vec![latest_height])
}

fn update_state_on_misbehaviour(
&self,
ctx: &mut E,
client_id: &ClientId,
client_message: Any,
) -> Result<(), ClientError> {
Ok(())
}

fn update_state_on_upgrade(
&self,
ctx: &mut E,
client_id: &ClientId,
upgraded_client_state: Any,
upgraded_consensus_state: Any,
) -> Result<Height, ClientError> {
let latest_height = ctx.client_state(client_id)?.latest_height().increment();

let new_client_state = ClientState { latest_height };

update_client_and_consensus_state(
ctx,
latest_height,
client_id,
upgraded_client_state.try_into()?,
upgraded_consensus_state.try_into()?,
)?;

Ok(latest_height)
}

fn update_on_recovery(
&self,
ctx: &mut E,
subject_client_id: &ClientId,
substitute_client_state: Any,
substitute_consensus_state: Any,
) -> Result<(), ClientError> {
let latest_height = ctx
.client_state(subject_client_id)?
.latest_height()
.increment();

let new_client_state = ClientState { latest_height };

update_client_and_consensus_state(
ctx,
latest_height,
subject_client_id,
substitute_client_state.try_into()?,
substitute_consensus_state.try_into()?,
)?;

Ok(())
}
}

fn update_client_and_consensus_state<E: ClientExecutionContext>(
ctx: &mut E,
client_height: Height,
client_id: &ClientId,
client_state: E::ClientStateRef,
consensus_state: E::ConsensusStateRef,
) -> Result<(), ClientError> {
ctx.store_consensus_state(
ClientConsensusStatePath::new(
client_id.clone(),
client_height.revision_number(),
client_height.revision_height(),
),
consensus_state,
)?;
ctx.store_client_state(ClientStatePath::new(client_id.clone()), client_state)?;
ctx.store_update_meta(
client_id.clone(),
client_height,
Timestamp::none(),
Height::min(0),
)?;

Ok(())
}
Loading

0 comments on commit 9ce305a

Please sign in to comment.