forked from informalsystems/hermes
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Relayer CLIs for client messages (informalsystems#251)
* relayer create client cli * Add conversion between MsgCreateClient and MsgCreateAnyClient * added forgotten file * added forgotten file * Move functionality in create_clien() to be used by the relayer * Remove ics07 messages * Cleanup * Move create_clien() in the relayer * Review comments * Review comments * Add new get_dummy_.. helper function * Remove backtrace from the output * Review comment
- Loading branch information
1 parent
4224310
commit f1e5103
Showing
12 changed files
with
251 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
//! `tx` subcommand | ||
use crate::commands::tx::client::TxCreateClientCmd; | ||
use abscissa_core::{Command, Options, Runnable}; | ||
|
||
mod client; | ||
|
||
/// `tx` subcommand | ||
#[derive(Command, Debug, Options, Runnable)] | ||
pub enum TxCmd { | ||
/// The `tx raw` subcommand submits IBC transactions to a chain | ||
#[options(help = "tx raw")] | ||
Raw(TxRawCommands), | ||
} | ||
|
||
#[derive(Command, Debug, Options, Runnable)] | ||
pub enum TxRawCommands { | ||
/// The `tx raw client-create` subcommand submits a MsgCreateClient in a transaction to a chain | ||
#[options(help = "tx raw create-client")] | ||
CreateClient(TxCreateClientCmd), | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
use abscissa_core::{Command, Options, Runnable}; | ||
use relayer::config::Config; | ||
use relayer::tx::client::{create_client, CreateClientOptions}; | ||
|
||
use crate::application::app_config; | ||
use crate::error::{Error, Kind}; | ||
use crate::prelude::*; | ||
|
||
#[derive(Clone, Command, Debug, Options)] | ||
pub struct TxCreateClientCmd { | ||
#[options(free, help = "identifier of the destination chain")] | ||
dest_chain_id: Option<String>, | ||
|
||
#[options(free, help = "identifier of the source chain")] | ||
src_chain_id: Option<String>, | ||
|
||
#[options( | ||
free, | ||
help = "identifier of the client to be created on destination chain" | ||
)] | ||
dest_client_id: Option<String>, | ||
} | ||
|
||
impl TxCreateClientCmd { | ||
fn validate_options(&self, config: &Config) -> Result<CreateClientOptions, String> { | ||
let dest_chain_id = self | ||
.dest_chain_id | ||
.clone() | ||
.ok_or_else(|| "missing destination chain identifier".to_string())?; | ||
|
||
let dest_chain_config = config | ||
.chains | ||
.iter() | ||
.find(|c| c.id == dest_chain_id.parse().unwrap()) | ||
.ok_or_else(|| "missing destination chain configuration".to_string())?; | ||
|
||
let src_chain_id = self | ||
.src_chain_id | ||
.clone() | ||
.ok_or_else(|| "missing source chain identifier".to_string())?; | ||
|
||
let src_chain_config = config | ||
.chains | ||
.iter() | ||
.find(|c| c.id == src_chain_id.parse().unwrap()) | ||
.ok_or_else(|| "missing source chain configuration".to_string())?; | ||
|
||
let dest_client_id = self | ||
.dest_client_id | ||
.as_ref() | ||
.ok_or_else(|| "missing destination client identifier".to_string())? | ||
.parse() | ||
.map_err(|_| "bad client identifier".to_string())?; | ||
|
||
Ok(CreateClientOptions { | ||
dest_client_id, | ||
dest_chain_config: dest_chain_config.clone(), | ||
src_chain_config: src_chain_config.clone(), | ||
}) | ||
} | ||
} | ||
|
||
impl Runnable for TxCreateClientCmd { | ||
fn run(&self) { | ||
let config = app_config(); | ||
|
||
let opts = match self.validate_options(&config) { | ||
Err(err) => { | ||
status_err!("invalid options: {}", err); | ||
return; | ||
} | ||
Ok(result) => result, | ||
}; | ||
status_info!("Message", "{:?}", opts); | ||
|
||
let res: Result<(), Error> = create_client(opts).map_err(|e| Kind::Tx.context(e).into()); | ||
|
||
match res { | ||
Ok(receipt) => status_info!("client created, result: ", "{:?}", receipt), | ||
Err(e) => status_info!("client create failed, error: ", "{}", e), | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,4 +18,5 @@ pub mod error; | |
pub mod event_handler; | ||
pub mod event_monitor; | ||
pub mod store; | ||
pub mod tx; | ||
pub mod util; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
pub mod client; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
use prost_types::Any; | ||
use std::time::Duration; | ||
|
||
use ibc::ics02_client::client_def::{AnyClientState, AnyConsensusState}; | ||
use ibc::ics02_client::client_type::ClientType; | ||
use ibc::ics02_client::msgs::MsgCreateAnyClient; | ||
use ibc::ics24_host::identifier::ClientId; | ||
use ibc::ics24_host::Path::ClientState as ClientStatePath; | ||
use ibc::tx_msg::Msg; | ||
|
||
use tendermint::block::Height; | ||
|
||
use crate::chain::cosmos::block_on; | ||
use crate::chain::{query_latest_header, Chain, CosmosSDKChain}; | ||
use crate::config::ChainConfig; | ||
use crate::error::{Error, Kind}; | ||
|
||
#[derive(Clone, Debug)] | ||
pub struct CreateClientOptions { | ||
pub dest_client_id: ClientId, | ||
pub dest_chain_config: ChainConfig, | ||
pub src_chain_config: ChainConfig, | ||
} | ||
|
||
pub fn create_client(opts: CreateClientOptions) -> Result<(), Error> { | ||
// Ger the destination | ||
let dest_chain = CosmosSDKChain::from_config(opts.clone().dest_chain_config)?; | ||
|
||
// Query the client state on destination chain. | ||
if dest_chain | ||
.query(ClientStatePath(opts.clone().dest_client_id), 0, false) | ||
.is_ok() | ||
{ | ||
return Err(Into::<Error>::into(Kind::CreateClient( | ||
opts.dest_client_id, | ||
"client already exists".into(), | ||
))); | ||
} | ||
|
||
// Get the latest header from the source chain and build the consensus state. | ||
let src_chain = CosmosSDKChain::from_config(opts.clone().src_chain_config)?; | ||
let tm_consensus_state = block_on(query_latest_header::<CosmosSDKChain>(&src_chain)) | ||
.map_err(|e| { | ||
Kind::CreateClient( | ||
opts.dest_client_id.clone(), | ||
"failed to get the latest header".into(), | ||
) | ||
.context(e) | ||
}) | ||
.map(ibc::ics07_tendermint::consensus_state::ConsensusState::from)?; | ||
|
||
let any_consensus_state = AnyConsensusState::Tendermint(tm_consensus_state.clone()); | ||
|
||
// Build the client state. | ||
let any_client_state = ibc::ics07_tendermint::client_state::ClientState::new( | ||
src_chain.id().to_string(), | ||
src_chain.trusting_period(), | ||
src_chain.unbonding_period(), | ||
Duration::from_millis(3000), | ||
tm_consensus_state.height, | ||
Height(0), | ||
) | ||
.map_err(|e| { | ||
Kind::CreateClient( | ||
opts.dest_client_id.clone(), | ||
"failed to build the client state".into(), | ||
) | ||
.context(e) | ||
}) | ||
.map(AnyClientState::Tendermint)?; | ||
|
||
let signer = dest_chain.config().account_prefix.parse().map_err(|e| { | ||
Kind::CreateClient(opts.dest_client_id.clone(), "bad signer".into()).context(e) | ||
})?; | ||
|
||
// Build the domain type message | ||
let new_msg = MsgCreateAnyClient::new( | ||
opts.dest_client_id, | ||
ClientType::Tendermint, | ||
any_client_state, | ||
any_consensus_state, | ||
signer, | ||
); | ||
|
||
// Create a proto any message | ||
let mut proto_msgs: Vec<Any> = Vec::new(); | ||
let any_msg = Any { | ||
// TODO - add get_url_type() to prepend proper string to get_type() | ||
type_url: "/ibc.client.MsgCreateClient".to_ascii_lowercase(), | ||
value: new_msg.get_sign_bytes(), | ||
}; | ||
|
||
proto_msgs.push(any_msg); | ||
dest_chain.send(&proto_msgs) | ||
} |