Skip to content

Commit

Permalink
feat(e2e): bootstrap connection and channel between starknet <> cosmos (
Browse files Browse the repository at this point in the history
#162)

* a is counterparty for conn open try message

* fix zero height

* fix typo for ConnectionCounterparty

* wip

* encode cometbft light client for cosmos

* fix empty proofs

* cargo fmt

* uncomment

* comment

* avoid zero heights

* channel handshake

* fix channel open try message build

* fix cairo test

* happy clippy

* uncomment ics20 packet_recv

* pick a recent light client height

* lint std_instead_of_core
  • Loading branch information
rnbguy authored Jan 6, 2025
1 parent f5a1452 commit d542304
Show file tree
Hide file tree
Showing 21 changed files with 181 additions and 469 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use starknet_ibc_core::client::{Height, HeightPartialOrd, Status, StatusTrait};
pub struct CometClientState {
pub latest_height: Height,
pub trusting_period: u64,
pub unbonding_period: u64,
pub status: Status,
}

Expand Down
3 changes: 3 additions & 0 deletions cairo-contracts/packages/testkit/src/configs/cometbft.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ pub struct CometClientConfig {
pub latest_height: Height,
pub latest_timestamp: u64,
pub trusting_period: u64,
pub unbonding_period: u64,
}

#[generate_trait]
Expand All @@ -23,6 +24,7 @@ pub impl CometClientConfigImpl of CometClientConfigTrait {
latest_height: HEIGHT(10),
latest_timestamp: 10,
trusting_period: 100,
unbonding_period: 200,
}
}

Expand All @@ -32,6 +34,7 @@ pub impl CometClientConfigImpl of CometClientConfigTrait {
let client_state = CometClientState {
latest_height: self.latest_height.clone(),
trusting_period: *self.trusting_period,
unbonding_period: *self.unbonding_period,
status: Status::Active,
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::marker::PhantomData;
use core::marker::PhantomData;

use cgp::core::error::HasErrorType;
use cgp::prelude::Cons;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::marker::PhantomData;
use core::marker::PhantomData;

use cgp::prelude::*;
use hermes_encoding_components::traits::decode_mut::MutDecoderComponent;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::marker::PhantomData;
use core::marker::PhantomData;

use cgp::core::error::HasErrorType;
use hermes_encoding_components::traits::decode_mut::MutDecoder;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::ops::Deref;
use core::ops::Deref;

use hermes_encoding_components::traits::encode_mut::{CanEncodeMut, MutEncoder};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::marker::PhantomData;
use core::marker::PhantomData;

use cgp::prelude::*;
use starknet::accounts::ConnectedAccount;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -197,9 +197,9 @@ where
counterparty_payload: ConnectionOpenTryPayload<Counterparty, Chain>,
) -> Result<Chain::Message, Chain::Error> {
// FIXME: Cairo IBC should accept counterparty client ID as string value
let cosmos_client_id_as_cairo = {
let cosmos_client_id_str = counterparty_client_id.to_string();
let (client_type, sequence_str) = cosmos_client_id_str
let counterparty_client_id_as_cairo = {
let counterparty_client_id_str = counterparty_client_id.to_string();
let (client_type, sequence_str) = counterparty_client_id_str
.rsplit_once('-')
.ok_or_else(|| Chain::raise_error("malformatted client id"))?;

Expand Down Expand Up @@ -230,8 +230,8 @@ where
};

let conn_open_init_msg: MsgConnOpenTry = MsgConnOpenTry {
client_id_on_a: client_id.clone(),
client_id_on_b: cosmos_client_id_as_cairo.clone(),
client_id_on_a: counterparty_client_id_as_cairo.clone(),
client_id_on_b: client_id.clone(),
conn_id_on_a: StarknetConnectionId {
connection_id: counterparty_connection_id.to_string(),
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ where
let client_state = CometClientState {
latest_height: height,
trusting_period: payload.client_state.trusting_period.as_secs(),
unbonding_period: payload.client_state.unbonding_period.as_secs(),
status: ClientStatus::Active,
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::marker::PhantomData;
use core::marker::PhantomData;

use cgp::prelude::*;
use starknet::providers::Provider;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use core::marker::PhantomData;
use cgp::prelude::*;
use hermes_cairo_encoding_components::strategy::ViaCairo;
use hermes_cairo_encoding_components::types::as_felt::AsFelt;
use hermes_chain_components::traits::queries::chain_status::CanQueryChainHeight;
use hermes_chain_components::traits::queries::channel_end::{
ChannelEndQuerier, ChannelEndWithProofsQuerier,
};
Expand Down Expand Up @@ -75,7 +76,8 @@ where
impl<Chain, Counterparty, Encoding> ChannelEndWithProofsQuerier<Chain, Counterparty>
for QueryChannelEndFromStarknet
where
Chain: HasHeightType
Chain: HasHeightType<Height = u64>
+ CanQueryChainHeight
+ HasChannelIdType<Counterparty, ChannelId = ChannelId>
+ HasPortIdType<Counterparty>
+ HasChannelEndType<Counterparty, ChannelEnd = ChannelEnd>
Expand Down Expand Up @@ -116,8 +118,8 @@ where

// TODO(rano): how to get the proof?
let dummy_proof = StarknetCommitmentProof {
proof_height: 0,
proof_bytes: vec![],
proof_height: chain.query_chain_height().await?,
proof_bytes: vec![0x1],
};

Ok((
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use core::marker::PhantomData;
use cgp::prelude::*;
use hermes_cairo_encoding_components::strategy::ViaCairo;
use hermes_cairo_encoding_components::types::as_felt::AsFelt;
use hermes_chain_components::traits::queries::chain_status::CanQueryChainHeight;
use hermes_chain_components::traits::queries::connection_end::{
ConnectionEndQuerier, ConnectionEndWithProofsQuerier,
};
Expand Down Expand Up @@ -66,7 +67,8 @@ where
impl<Chain, Counterparty, Encoding> ConnectionEndWithProofsQuerier<Chain, Counterparty>
for QueryConnectionEndFromStarknet
where
Chain: HasHeightType
Chain: HasHeightType<Height = u64>
+ CanQueryChainHeight
+ HasCommitmentProofType<CommitmentProof = StarknetCommitmentProof>
+ HasConnectionIdType<Counterparty, ConnectionId = ConnectionId>
+ HasConnectionEndType<Counterparty, ConnectionEnd = ConnectionEnd>
Expand Down Expand Up @@ -99,8 +101,8 @@ where

// TODO(rano): how to get the proof?
let dummy_proof = StarknetCommitmentProof {
proof_height: 0,
proof_bytes: vec![],
proof_height: chain.query_chain_height().await?,
proof_bytes: vec![0x1],
};

Ok((
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::convert::Infallible;
use core::convert::Infallible;
use core::num::ParseIntError;

use cgp::prelude::*;
use hermes_chain_components::traits::message_builders::channel_handshake::{
Expand Down Expand Up @@ -28,10 +29,7 @@ use ibc::core::client::types::Height as CosmosHeight;
use ibc::core::host::types::error::IdentifierError;
use ibc::core::host::types::identifiers::{ChannelId as IbcChannelId, PortId as IbcPortId};

use crate::types::channel_id::{
ChannelEnd as StarknetChannelEnd, ChannelId as StarknetChannelId,
ChannelState as StarknetChannelState,
};
use crate::types::channel_id::{ChannelEnd as StarknetChannelEnd, ChannelId as StarknetChannelId};
use crate::types::commitment_proof::StarknetCommitmentProof;
use crate::types::messages::ibc::channel::ChannelOrdering as StarknetChannelOrdering;

Expand All @@ -44,6 +42,8 @@ where
+ HasPortIdType<Counterparty, PortId = IbcPortId>
+ CanRaiseError<Infallible>
+ CanRaiseError<ClientError>
+ CanRaiseError<&'static str>
+ CanRaiseError<ParseIntError>
+ CanRaiseError<IdentifierError>,
Counterparty: HasChannelIdType<Chain, ChannelId = StarknetChannelId>
+ HasPortIdType<Chain, PortId = IbcPortId>
Expand All @@ -58,43 +58,36 @@ where
async fn build_channel_open_try_message(
_chain: &Chain,
port_id: &IbcPortId,
_counterparty_port_id: &IbcPortId,
_counterparty_channel_id: &StarknetChannelId,
counterparty_port_id: &IbcPortId,
counterparty_channel_id: &StarknetChannelId,
counterparty_payload: ChannelOpenTryPayload<Counterparty, Chain>,
) -> Result<Chain::Message, Chain::Error> {
let update_height =
CosmosHeight::new(0, counterparty_payload.update_height).map_err(Chain::raise_error)?;

let starknet_channel_end = counterparty_payload.channel_end;

let state = match starknet_channel_end.state {
StarknetChannelState::Uninitialized => IbcChannelState::Uninitialized,
StarknetChannelState::Init => IbcChannelState::Init,
StarknetChannelState::TryOpen => IbcChannelState::TryOpen,
StarknetChannelState::Open => IbcChannelState::Open,
StarknetChannelState::Closed => IbcChannelState::Closed,
};

let ordering = match starknet_channel_end.ordering {
StarknetChannelOrdering::Ordered => IbcChannelOrder::Ordered,
StarknetChannelOrdering::Unordered => IbcChannelOrder::Unordered,
};

if !starknet_channel_end.remote.channel_id.channel_id.is_empty() {
return Err(Chain::raise_error(
"ChannelEnd has non-empty channel_id after chan_open_init",
));
}

let cosmos_channel_seq = counterparty_channel_id
.channel_id
.strip_prefix("channel-")
.ok_or_else(|| Chain::raise_error("ChannelId does not have the expected prefix"))?
.parse::<u64>()
.map_err(Chain::raise_error)?;

let remote = IbcChannelCounterparty {
port_id: starknet_channel_end
.remote
.port_id
.port_id
.parse()
.map_err(Chain::raise_error)?,
channel_id: Some(
starknet_channel_end
.remote
.channel_id
.channel_id
.parse()
.map_err(Chain::raise_error)?,
),
port_id: counterparty_port_id.clone(),
channel_id: Some(IbcChannelId::new(cosmos_channel_seq)),
};

let connection_id = starknet_channel_end
Expand All @@ -111,7 +104,7 @@ where

// TODO(rano): how to get channel end here ?
let channel_end = IbcChannelEnd {
state,
state: IbcChannelState::TryOpen,
ordering,
remote,
connection_hops: vec![connection_id],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ use ibc::core::connection::types::version::Version as CosmosConnectionVersion;
use ibc::core::host::types::identifiers::{
ClientId as CosmosClientId, ConnectionId as CosmosConnectionId,
};
use ibc::primitives::proto::Any as IbcProtoAny;
use prost_types::Any;

use crate::types::client_id::ClientId as StarknetClientId;
Expand Down Expand Up @@ -100,34 +101,37 @@ where
counterparty_connection_id: &StarknetConnectionId,
counterparty_payload: ConnectionOpenTryPayload<Counterparty, Chain>,
) -> Result<Chain::Message, Chain::Error> {
// TODO(rano): dummy client state.
// we need to replace CometClientState with real tendermint ClientState
let client_state_any = Any {
type_url: "".to_string(),
value: vec![],
};
let ibc_client_state_any = IbcProtoAny::from(counterparty_payload.client_state);

// TODO(rano): dummy connection version
let counterparty_versions = CosmosConnectionVersion::compatibles();

// TODO(rano): delay period
let delay_period = Duration::from_secs(0);

// TODO(rano): apparently update height is set to zero
let update_height =
CosmosHeight::new(0, counterparty_payload.update_height).map_err(Chain::raise_error)?;
CosmosHeight::new(0, core::cmp::max(1, counterparty_payload.update_height))
.map_err(Chain::raise_error)?;

let message = CosmosConnectionOpenTryMessage {
client_id: client_id.to_string(),
counterparty_client_id: counterparty_client_id.to_string(),
counterparty_connection_id: counterparty_connection_id.to_string(),
counterparty_commitment_prefix: counterparty_payload.commitment_prefix,
counterparty_versions,
client_state: client_state_any,
client_state: Any {
type_url: ibc_client_state_any.type_url,
value: ibc_client_state_any.value,
},
delay_period,
update_height,
proof_init: counterparty_payload.proof_init.proof_bytes,
proof_client: counterparty_payload.proof_client.proof_bytes,
proof_consensus: counterparty_payload.proof_consensus.proof_bytes,
// TODO(rano): counterparty_payload has empty proofs?
// proof_client: counterparty_payload.proof_client.proof_bytes,
proof_client: vec![0x1],
// proof_consensus: counterparty_payload.proof_consensus.proof_bytes,
proof_consensus: vec![0x1],
proof_consensus_height: counterparty_payload.proof_consensus_height,
};

Expand Down Expand Up @@ -157,12 +161,7 @@ where
counterparty_connection_id: &StarknetConnectionId,
counterparty_payload: ConnectionOpenAckPayload<Counterparty, Chain>,
) -> Result<Chain::Message, Chain::Error> {
// TODO(rano): dummy client state.
// we need to replace CometClientState with real tendermint ClientState
let client_state_any = Any {
type_url: "".to_string(),
value: vec![],
};
let client_state_any = IbcProtoAny::from(counterparty_payload.client_state);

// TODO(rano): dummy connection version
let counterparty_versions = CosmosConnectionVersion::compatibles();
Expand All @@ -174,11 +173,17 @@ where
connection_id: connection_id.to_string(),
counterparty_connection_id: counterparty_connection_id.to_string(),
version: counterparty_versions[0].clone().into(),
client_state: client_state_any,
client_state: Any {
type_url: client_state_any.type_url,
value: client_state_any.value,
},
update_height,
proof_try: counterparty_payload.proof_try.proof_bytes,
proof_client: counterparty_payload.proof_client.proof_bytes,
proof_consensus: counterparty_payload.proof_consensus.proof_bytes,
// TODO(rano): counterparty_payload has empty proofs?
// proof_client: counterparty_payload.proof_client.proof_bytes,
proof_client: vec![0x1],
// proof_consensus: counterparty_payload.proof_consensus.proof_bytes,
proof_consensus: vec![0x1],
proof_consensus_height: counterparty_payload.proof_consensus_height,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ impl Display for ConnectionId {
pub struct ConnectionEnd {
pub state: ConnectionState,
pub client_id: ClientId,
pub counterparty: ConnectionState,
pub counterparty: ConnectionCounterparty,
pub version: ConnectionVersion,
pub delay_period: u64,
}
Expand All @@ -71,7 +71,7 @@ impl Transformer for EncodeConnectionEnd {
type From = Product![
ConnectionState,
ClientId,
ConnectionState,
ConnectionCounterparty,
ConnectionVersion,
u64
];
Expand Down
Loading

0 comments on commit d542304

Please sign in to comment.