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

Introduce 'create connection' cmd #688

Merged
merged 19 commits into from
Mar 1, 2021
Merged
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
- [nothing yet]

- [ibc-relayer-cli]
- Added `create connection` CLI ([#630])
- Proposed ADR 006 to describe Hermes v0.2.0 use-cases ([#637])

### IMPROVEMENTS
Expand Down Expand Up @@ -56,6 +57,7 @@

[#561]: https://github.com/informalsystems/ibc-rs/issues/561
[#599]: https://github.com/informalsystems/ibc-rs/issues/599
[#630]: https://github.com/informalsystems/ibc-rs/issues/630
[#672]: https://github.com/informalsystems/ibc-rs/issues/672
[#685]: https://github.com/informalsystems/ibc-rs/issues/685
[#689]: https://github.com/informalsystems/ibc-rs/issues/689
Expand Down
15 changes: 10 additions & 5 deletions modules/src/ics02_client/client_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::ics07_tendermint::client_state::ClientState as TendermintClientState;
use crate::ics07_tendermint::consensus_state::ConsensusState as TendermintConsensusState;
use crate::ics07_tendermint::header::Header as TendermintHeader;
use crate::ics23_commitment::commitment::{CommitmentPrefix, CommitmentProofBytes, CommitmentRoot};
use crate::ics24_host::identifier::{ChannelId, ClientId, ConnectionId, PortId};
use crate::ics24_host::identifier::{ChainId, ChannelId, ClientId, ConnectionId, PortId};
use crate::Height;

#[cfg(any(test, feature = "mocks"))]
Expand Down Expand Up @@ -211,7 +211,7 @@ impl TryFrom<Any> for AnyClientState {

fn try_from(raw: Any) -> Result<Self, Self::Error> {
match raw.type_url.as_str() {
"" => Err(Kind::EmptyClientState.into()),
"" => Err(Kind::EmptyClientStateResponse.into()),

TENDERMINT_CLIENT_STATE_TYPE_URL => Ok(AnyClientState::Tendermint(
TendermintClientState::decode_vec(&raw.value)
Expand Down Expand Up @@ -246,8 +246,13 @@ impl From<AnyClientState> for Any {
}

impl ClientState for AnyClientState {
fn chain_id(&self) -> String {
todo!()
fn chain_id(&self) -> ChainId {
match self {
AnyClientState::Tendermint(tm_state) => tm_state.chain_id(),

#[cfg(any(test, feature = "mocks"))]
AnyClientState::Mock(mock_state) => mock_state.chain_id(),
}
}

fn client_type(&self) -> ClientType {
Expand Down Expand Up @@ -299,7 +304,7 @@ impl TryFrom<Any> for AnyConsensusState {

fn try_from(value: Any) -> Result<Self, Self::Error> {
match value.type_url.as_str() {
"" => Err(Kind::EmptyConsensusState.into()),
"" => Err(Kind::EmptyConsensusStateResponse.into()),

TENDERMINT_CONSENSUS_STATE_TYPE_URL => Ok(AnyConsensusState::Tendermint(
TendermintConsensusState::decode_vec(&value.value)
Expand Down
8 changes: 4 additions & 4 deletions modules/src/ics02_client/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ pub enum Kind {
#[error("unknown client state type: {0}")]
UnknownClientStateType(String),

#[error("empty client state")]
EmptyClientState,
#[error("the client state was not found")]
EmptyClientStateResponse,

#[error("unknown client consensus state type: {0}")]
UnknownConsensusStateType(String),

#[error("empty client consensus state")]
EmptyConsensusState,
#[error("the client consensus state was not found")]
EmptyConsensusStateResponse,

#[error("unknown header type: {0}")]
UnknownHeaderType(String),
Expand Down
3 changes: 2 additions & 1 deletion modules/src/ics02_client/handler/create_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,9 @@ mod tests {
let ctx = MockContext::default();

let tm_header = get_dummy_tendermint_header();

let tm_client_state = AnyClientState::Tendermint(ClientState {
chain_id: tm_header.chain_id.to_string(),
chain_id: tm_header.chain_id.clone().into(),
trust_level: TrustThreshold {
numerator: 1,
denominator: 3,
Expand Down
11 changes: 7 additions & 4 deletions modules/src/ics02_client/state.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use crate::ics23_commitment::commitment::CommitmentRoot;
use crate::ics24_host::identifier::ChainId;
use crate::Height;

use super::{
client_def::{AnyClientState, AnyConsensusState},
client_type::ClientType,
};
use crate::ics23_commitment::commitment::CommitmentRoot;
use crate::Height;

#[dyn_clonable::clonable]
pub trait ConsensusState: Clone + std::fmt::Debug + Send + Sync {
Expand All @@ -22,8 +24,9 @@ pub trait ConsensusState: Clone + std::fmt::Debug + Send + Sync {

#[dyn_clonable::clonable]
pub trait ClientState: Clone + std::fmt::Debug + Send + Sync {
/// Client ID of this state
fn chain_id(&self) -> String;
/// Return the chain identifier which this client is serving (i.e., the client is verifying
/// consensus states from this chain).
fn chain_id(&self) -> ChainId;

/// Type of client associated with this state (eg. Tendermint)
fn client_type(&self) -> ClientType;
Expand Down
7 changes: 6 additions & 1 deletion modules/src/ics03_connection/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ impl From<ConnectionEnd> for RawConnectionEnd {
.collect(),
state: value.state as i32,
counterparty: Some(value.counterparty.into()),
delay_period: 0,
delay_period: value.delay_period,
}
}
}
Expand Down Expand Up @@ -148,6 +148,11 @@ impl ConnectionEnd {
self.counterparty.clone()
}

/// Getter for the delay_period field.
pub fn delay_period(&self) -> u64 {
self.delay_period
}

/// TODO: Clean this up, probably not necessary.
pub fn validate_basic(&self) -> Result<(), ValidationError> {
self.counterparty.validate_basic()
Expand Down
2 changes: 1 addition & 1 deletion modules/src/ics03_connection/msgs/conn_open_try.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ impl From<MsgConnectionOpenTry> for RawMsgConnectionOpenTry {
.client_state
.map_or_else(|| None, |v| Some(v.into())),
counterparty: Some(ics_msg.counterparty.into()),
delay_period: 0,
delay_period: ics_msg.delay_period,
counterparty_versions: ics_msg
.counterparty_versions
.iter()
Expand Down
29 changes: 20 additions & 9 deletions modules/src/ics07_tendermint/client_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use std::convert::{TryFrom, TryInto};
use std::time::Duration;

use serde::Serialize;

use tendermint::trust_threshold::TrustThresholdFraction as TrustThreshold;
use tendermint_proto::Protobuf;

Expand All @@ -13,11 +12,12 @@ use crate::ics02_client::client_type::ClientType;
use crate::ics07_tendermint::error::{Error, Kind};
use crate::ics07_tendermint::header::Header;
use crate::ics23_commitment::merkle::cosmos_specs;
use crate::ics24_host::identifier::ChainId;
use crate::Height;

#[derive(Clone, Debug, PartialEq, Eq, Serialize)]
pub struct ClientState {
pub chain_id: String,
pub chain_id: ChainId,
pub trust_level: TrustThreshold,
pub trusting_period: Duration,
pub unbonding_period: Duration,
Expand All @@ -35,7 +35,7 @@ impl Protobuf<RawClientState> for ClientState {}
impl ClientState {
#[allow(clippy::too_many_arguments)]
pub fn new(
chain_id: String,
chain_id: ChainId,
trust_level: TrustThreshold,
trusting_period: Duration,
unbonding_period: Duration,
Expand Down Expand Up @@ -106,7 +106,7 @@ impl ClientState {
}

impl crate::ics02_client::state::ClientState for ClientState {
fn chain_id(&self) -> String {
fn chain_id(&self) -> ChainId {
self.chain_id.clone()
}

Expand Down Expand Up @@ -134,10 +134,17 @@ impl TryFrom<RawClientState> for ClientState {
fn try_from(raw: RawClientState) -> Result<Self, Self::Error> {
let trust_level = raw
.trust_level
.clone()
.ok_or_else(|| Kind::InvalidRawClientState.context("missing trusting period"))?;

let chain_id = raw
.chain_id
.clone()
.try_into()
.map_err(|e| Kind::InvalidChainId(raw.chain_id.clone(), e))?;

Ok(Self {
chain_id: raw.chain_id,
chain_id,
trust_level: TrustThreshold {
numerator: trust_level.numerator,
denominator: trust_level.denominator,
Expand Down Expand Up @@ -177,7 +184,7 @@ impl TryFrom<RawClientState> for ClientState {
impl From<ClientState> for RawClientState {
fn from(value: ClientState) -> Self {
RawClientState {
chain_id: value.chain_id.clone(),
chain_id: value.chain_id.to_string(),
trust_level: Some(Fraction {
numerator: value.trust_level.numerator,
denominator: value.trust_level.denominator,
Expand All @@ -203,6 +210,7 @@ mod tests {
use tendermint_rpc::endpoint::abci_query::AbciQuery;

use crate::ics07_tendermint::client_state::ClientState;
use crate::ics24_host::identifier::ChainId;
use crate::test::test_serialization_roundtrip;
use crate::Height;

Expand All @@ -225,7 +233,7 @@ mod tests {
fn client_state_new() {
#[derive(Clone, Debug, PartialEq)]
struct ClientStateParams {
id: String,
id: ChainId,
trust_level: TrustThreshold,
trusting_period: Duration,
unbonding_period: Duration,
Expand All @@ -239,7 +247,7 @@ mod tests {

// Define a "default" set of parameters to reuse throughout these tests.
let default_params: ClientStateParams = ClientStateParams {
id: "thisisthechainid".to_string(),
id: ChainId::default(),
trust_level: TrustThreshold {
numerator: 1,
denominator: 3,
Expand Down Expand Up @@ -333,6 +341,7 @@ mod tests {

#[cfg(any(test, feature = "mocks"))]
pub mod test_util {
use std::convert::TryInto;
use std::time::Duration;

use tendermint::block::Header;
Expand All @@ -343,9 +352,11 @@ pub mod test_util {
use crate::ics24_host::identifier::ChainId;

pub fn get_dummy_tendermint_client_state(tm_header: Header) -> AnyClientState {
let chain_id: ChainId = tm_header.chain_id.clone().try_into().unwrap();

AnyClientState::Tendermint(
ClientState::new(
tm_header.chain_id.to_string(),
chain_id,
Default::default(),
Duration::from_secs(64000),
Duration::from_secs(128000),
Expand Down
7 changes: 6 additions & 1 deletion modules/src/ics07_tendermint/error.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
use anomaly::{BoxError, Context};
use thiserror::Error;

use crate::ics24_host::error::ValidationKind;

pub type Error = anomaly::Error<Kind>;

#[derive(Clone, Debug, Error)]
pub enum Kind {
#[error("invalid trusting period")]
InvalidTrustingPeriod,

#[error("invalid unbounding period")]
#[error("invalid unbonding period")]
InvalidUnboundingPeriod,

#[error("invalid address")]
Expand All @@ -23,6 +25,9 @@ pub enum Kind {
#[error("invalid raw client state")]
InvalidRawClientState,

#[error("invalid chain identifier: raw value {0} with underlying validation error: {1}")]
InvalidChainId(String, ValidationKind),

#[error("invalid raw height")]
InvalidRawHeight,

Expand Down
10 changes: 10 additions & 0 deletions modules/src/ics24_host/identifier.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
use std::convert::TryFrom;
use std::str::FromStr;

use serde::{Deserialize, Serialize};

use crate::ics02_client::client_type::ClientType;
use crate::ics24_host::error::ValidationKind;

use super::error::ValidationError;
use super::validate::*;
Expand Down Expand Up @@ -115,6 +117,14 @@ impl Default for ChainId {
}
}

impl TryFrom<String> for ChainId {
type Error = ValidationKind;

fn try_from(value: String) -> Result<Self, Self::Error> {
Self::from_str(value.as_str()).map_err(|e| e.kind().clone())
}
}

#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct ClientId(String);

Expand Down
3 changes: 2 additions & 1 deletion modules/src/mock/client_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use crate::ics02_client::error::Error;
use crate::ics02_client::error::Kind;
use crate::ics02_client::state::{ClientState, ConsensusState};
use crate::ics23_commitment::commitment::CommitmentRoot;
use crate::ics24_host::identifier::ChainId;
use crate::mock::header::MockHeader;
use crate::Height;

Expand Down Expand Up @@ -69,7 +70,7 @@ impl From<MockClientState> for RawMockClientState {
}

impl ClientState for MockClientState {
fn chain_id(&self) -> String {
fn chain_id(&self) -> ChainId {
todo!()
}

Expand Down
9 changes: 7 additions & 2 deletions relayer-cli/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@ use crate::commands::channel::ChannelCmds;
use crate::config::Config;

use self::{
keys::KeysCmd, light::LightCmd, listen::ListenCmd, query::QueryCmd, start::StartCmd, tx::TxCmd,
version::VersionCmd,
create::CreateCmds, keys::KeysCmd, light::LightCmd, listen::ListenCmd, query::QueryCmd,
start::StartCmd, tx::TxCmd, version::VersionCmd,
};

mod channel;
mod cli_utils;
mod config;
mod create;
mod keys;
mod light;
mod listen;
Expand Down Expand Up @@ -53,6 +54,10 @@ pub enum CliCmd {
#[options(help = "Basic functionality for managing the light clients")]
Light(LightCmd),

/// The `create` subcommand
#[options(help = "Create objects on chains")]
Create(CreateCmds),

/// The `start` subcommand
#[options(help = "Start the relayer")]
Start(StartCmd),
Expand Down
Loading