Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement IBC handler components #41

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
443 changes: 382 additions & 61 deletions Cargo.lock

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ members = [
"crates/relayer-runtime",
"crates/relayer-cosmos",
"crates/relayer-cosmos-mock",
"crates/ibc-framework",
"crates/ibc-cosmos",
"tools/integration-test",
"tools/test-framework",
]
Expand All @@ -23,6 +25,7 @@ exclude = [
overflow-checks = true

[patch.crates-io]
ibc = { version = "0.27.0", git = "https://github.com/cosmos/ibc-rs.git", branch = "soares/relayer-next" }
cgp-core = { git = "https://github.com/informalsystems/cgp.git", branch = "main" }
cgp-macros = { git = "https://github.com/informalsystems/cgp.git", branch = "main" }
ibc-relayer-types = { git = "https://github.com/informalsystems/hermes.git", branch = "master" }
Expand Down
27 changes: 27 additions & 0 deletions crates/ibc-cosmos/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
[package]
name = "ibc-cosmos"
version = "0.19.0"
edition = "2021"
license = "Apache-2.0"
readme = "README.md"
keywords = ["blockchain", "consensus", "cosmos", "ibc", "tendermint"]
repository = "https://github.com/informalsystems/ibc-rs"
authors = ["Informal Systems <[email protected]>"]
rust-version = "1.60"
description = """
Implementation of an IBC Relayer in Rust, as a library
"""

[package.metadata.docs.rs]
all-features = true

[features]

[dependencies]
async-trait = "0.1.56"
ibc = { version = "0.27.0" }
ibc-proto = { version = "0.24.0" }
ibc-framework = { version = "0.1.0", path = "../ibc-framework" }
tendermint = { version = "=0.28.0", default-features = false }
tendermint-proto = { version = "=0.28.0", default-features = false }
tendermint-light-client-verifier = { version = "=0.28.0", default-features = false }
1 change: 1 addition & 0 deletions crates/ibc-cosmos/src/all_for_one/instances/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod update_client;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod tendermint;
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use core::marker::PhantomData;
use ibc_framework::core::impls::handlers::update_client::lift::LiftClientUpdateHandler;
use ibc_framework::core::traits::handlers::update_client::{
AnyUpdateClientHandler, UpdateClientHandler,
};

use crate::all_for_one::traits::dynamic::AfoDynamicChainContext;
use crate::all_for_one::traits::tendermint::AfoTendermintOnlyChainContext;
use crate::clients::tendermint::client::TendermintClient;

pub fn can_build_tendermint_update_handler<Context>(
) -> PhantomData<impl UpdateClientHandler<Context>>
where
Context: AfoTendermintOnlyChainContext,
{
PhantomData::<TendermintClient>
}

pub fn can_build_tendermint_any_update_handler<Context>(
) -> PhantomData<impl AnyUpdateClientHandler<Context>>
where
Context: AfoTendermintOnlyChainContext,
{
PhantomData::<LiftClientUpdateHandler<TendermintClient>>
}

pub fn can_build_dynamic_tendermint_any_update_handler<Context>(
) -> PhantomData<impl AnyUpdateClientHandler<Context>>
where
Context: AfoDynamicChainContext,
{
PhantomData::<LiftClientUpdateHandler<TendermintClient>>
}
2 changes: 2 additions & 0 deletions crates/ibc-cosmos/src/all_for_one/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod instances;
pub mod traits;
46 changes: 46 additions & 0 deletions crates/ibc-cosmos/src/all_for_one/traits/dynamic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use ibc::core::ics23_commitment::merkle::MerkleProof;
use ibc::core::ics24_host::identifier::ClientId;
use ibc::timestamp::Timestamp;
use ibc::Height;
use ibc_framework::all_for_one::traits::base::AfoChainContext;
use ibc_framework::core::traits::error::InjectError;
use ibc_framework::core::traits::stores::client_reader::HasClientReader;
use ibc_proto::google::protobuf::Any;

use crate::clients::dynamic::client::{
DynClientHeader, DynClientState, DynConsensusState, DynMisbehavior,
};
use crate::clients::tendermint::client::TendermintClient;
use crate::clients::tendermint::update_client::Error as UpdateTendermintClientError;

pub trait AfoDynamicChainContext:
AfoChainContext<
Height = Height,
Timestamp = Timestamp,
Message = Any,
ClientId = ClientId,
MerkleProof = MerkleProof,
AnyClientState = DynClientState,
AnyConsensusState = DynConsensusState,
AnyClientHeader = DynClientHeader,
AnyMisbehavior = DynMisbehavior,
> + InjectError<UpdateTendermintClientError>
+ HasClientReader<TendermintClient>
{
}

impl<Context> AfoDynamicChainContext for Context where
Context: AfoChainContext<
Height = Height,
Timestamp = Timestamp,
Message = Any,
ClientId = ClientId,
MerkleProof = MerkleProof,
AnyClientState = DynClientState,
AnyConsensusState = DynConsensusState,
AnyClientHeader = DynClientHeader,
AnyMisbehavior = DynMisbehavior,
> + InjectError<UpdateTendermintClientError>
+ HasClientReader<TendermintClient>
{
}
2 changes: 2 additions & 0 deletions crates/ibc-cosmos/src/all_for_one/traits/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod dynamic;
pub mod tendermint;
46 changes: 46 additions & 0 deletions crates/ibc-cosmos/src/all_for_one/traits/tendermint.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use ibc::core::ics23_commitment::merkle::MerkleProof;
use ibc::core::ics24_host::identifier::ClientId;
use ibc::timestamp::Timestamp;
use ibc::Height;
use ibc_framework::all_for_one::traits::base::AfoChainContext;
use ibc_framework::core::traits::error::InjectError;
use ibc_framework::core::traits::stores::client_reader::HasClientReader;
use ibc_proto::google::protobuf::Any;

use crate::clients::tendermint::client::{
TendermintClient, TendermintClientHeader, TendermintClientState, TendermintConsensusState,
TendermintMisbehavior,
};
use crate::clients::tendermint::update_client::Error as UpdateTendermintClientError;

pub trait AfoTendermintOnlyChainContext:
AfoChainContext<
Height = Height,
Timestamp = Timestamp,
Message = Any,
ClientId = ClientId,
MerkleProof = MerkleProof,
AnyClientState = TendermintClientState,
AnyConsensusState = TendermintConsensusState,
AnyClientHeader = TendermintClientHeader,
AnyMisbehavior = TendermintMisbehavior,
> + InjectError<UpdateTendermintClientError>
+ HasClientReader<TendermintClient>
{
}

impl<Context> AfoTendermintOnlyChainContext for Context where
Context: AfoChainContext<
Height = Height,
Timestamp = Timestamp,
Message = Any,
ClientId = ClientId,
MerkleProof = MerkleProof,
AnyClientState = TendermintClientState,
AnyConsensusState = TendermintConsensusState,
AnyClientHeader = TendermintClientHeader,
AnyMisbehavior = TendermintMisbehavior,
> + InjectError<UpdateTendermintClientError>
+ HasClientReader<TendermintClient>
{
}
178 changes: 178 additions & 0 deletions crates/ibc-cosmos/src/clients/dynamic/client.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
use core::time::Duration;
use ibc::clients::ics07_tendermint::client_state::ClientState as TendermintClientState;
use ibc::clients::ics07_tendermint::client_type as tendermint_client_type;
use ibc::clients::ics07_tendermint::consensus_state::ConsensusState as TendermintConsensusState;
use ibc::clients::ics07_tendermint::header::Header as TendermintClientHeader;
use ibc::clients::ics07_tendermint::misbehaviour::Misbehaviour as TendermintMisbehavior;
use ibc::core::ics02_client::client_state::ClientState;
use ibc::core::ics02_client::client_type::ClientType;
use ibc::core::ics02_client::consensus_state::ConsensusState;
use ibc::core::ics02_client::header::Header as ClientHeader;
use ibc::core::ics02_client::misbehaviour::Misbehaviour;
use ibc::timestamp::Timestamp;
use ibc::Height;
use ibc_framework::core::traits::client::{
HasAnyClientMethods, HasAnyClientTypes, HasClientTypeFor,
};
use ibc_framework::core::traits::host::HasHostTypes;
use ibc_framework::core::traits::prism::Prism;

use crate::clients::tendermint::client::TendermintClient;

pub struct DynamicClient;

pub struct DynClientState {
pub client_state: Box<dyn ClientState>,
}

pub struct DynConsensusState {
pub consensus_state: Box<dyn ConsensusState>,
}

pub struct DynClientHeader {
pub client_header: Box<dyn ClientHeader>,
}

pub struct DynMisbehavior {
pub misbehavior: Box<dyn Misbehaviour>,
}

impl HasAnyClientTypes for DynamicClient {
type ClientType = ClientType;

type AnyClientState = DynClientState;

type AnyConsensusState = DynConsensusState;

type AnyClientHeader = DynClientHeader;

type AnyMisbehavior = DynMisbehavior;
}

impl Prism<DynClientState, TendermintClientState> for DynamicClient {
fn into(client_state: TendermintClientState) -> DynClientState {
DynClientState::new(client_state)
}

fn try_from(client_state: DynClientState) -> Option<TendermintClientState> {
Self::try_from_ref(&client_state).cloned()
}

fn try_from_ref(client_state: &DynClientState) -> Option<&TendermintClientState> {
client_state.client_state.as_any().downcast_ref()
}
}

impl Prism<DynConsensusState, TendermintConsensusState> for DynamicClient {
fn into(consensus_state: TendermintConsensusState) -> DynConsensusState {
DynConsensusState::new(consensus_state)
}

fn try_from(consensus_state: DynConsensusState) -> Option<TendermintConsensusState> {
Self::try_from_ref(&consensus_state).cloned()
}

fn try_from_ref(consensus_state: &DynConsensusState) -> Option<&TendermintConsensusState> {
consensus_state.consensus_state.as_any().downcast_ref()
}
}

impl Prism<DynClientHeader, TendermintClientHeader> for DynamicClient {
fn into(client_header: TendermintClientHeader) -> DynClientHeader {
DynClientHeader::new(client_header)
}

fn try_from(client_header: DynClientHeader) -> Option<TendermintClientHeader> {
Self::try_from_ref(&client_header).cloned()
}

fn try_from_ref(client_header: &DynClientHeader) -> Option<&TendermintClientHeader> {
client_header.client_header.as_any().downcast_ref()
}
}

impl Prism<DynMisbehavior, TendermintMisbehavior> for DynamicClient {
fn into(misbehavior: TendermintMisbehavior) -> DynMisbehavior {
DynMisbehavior::new(misbehavior)
}

fn try_from(misbehavior: DynMisbehavior) -> Option<TendermintMisbehavior> {
Self::try_from_ref(&misbehavior).cloned()
}

fn try_from_ref(misbehavior: &DynMisbehavior) -> Option<&TendermintMisbehavior> {
misbehavior.misbehavior.as_any().downcast_ref()
}
}

impl HasClientTypeFor<TendermintClient> for DynamicClient {
fn client_type() -> Self::ClientType {
tendermint_client_type()
}
}

impl HasHostTypes for DynamicClient {
type Height = Height;

type Timestamp = Timestamp;

type Duration = Duration;
}

impl HasAnyClientMethods for DynamicClient {
fn client_state_type(client_state: &DynClientState) -> Self::ClientType {
client_state.client_state.client_type()
}

fn client_state_is_frozen(client_state: &DynClientState) -> bool {
client_state.client_state.is_frozen()
}

fn client_state_trusting_period(client_state: &DynClientState) -> Self::Duration {
client_state.client_state.trusting_period()
}

fn client_state_latest_height(client_state: &DynClientState) -> Self::Height {
client_state.client_state.latest_height()
}

fn consensus_state_timestamp(consensus_state: &DynConsensusState) -> Self::Timestamp {
consensus_state.consensus_state.timestamp()
}

fn client_header_height(client_header: &DynClientHeader) -> Self::Height {
client_header.client_header.height()
}
}

impl DynClientState {
fn new(client_state: impl ClientState) -> Self {
Self {
client_state: Box::new(client_state),
}
}
}

impl DynConsensusState {
fn new(consensus_state: impl ConsensusState) -> Self {
Self {
consensus_state: Box::new(consensus_state),
}
}
}

impl DynClientHeader {
fn new(client_header: impl ClientHeader) -> Self {
Self {
client_header: Box::new(client_header),
}
}
}

impl DynMisbehavior {
fn new(misbehavior: impl Misbehaviour) -> Self {
Self {
misbehavior: Box::new(misbehavior),
}
}
}
1 change: 1 addition & 0 deletions crates/ibc-cosmos/src/clients/dynamic/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod client;
2 changes: 2 additions & 0 deletions crates/ibc-cosmos/src/clients/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub mod dynamic;
pub mod tendermint;
Loading