Skip to content

Commit

Permalink
ConnOpenInit from the CLI (#246)
Browse files Browse the repository at this point in the history
* Initial implementation for the relayer tx command #206

* Adding initial logic to support signing #47

* Adding logic for auth tx

* Implementing initial support to conn open init and tx #206

* Changes:
- Implemented logic for tx raw connection open init
- Logic to build the message only using protobuf types
- Got some signing logic but not validated
- Still needs lots of refactoring and cleaning

* update signing code to use  k256

* Ignore .idea

* Refactoring the ConnOpenInit logic. Disabling the build and sign tx code #246

* Added logic for the conn init tx on relayer

* Finished implementing MsgConnectionOpenInit. No signing implemented #246

Co-authored-by: Andy Nogueira <me@andynogueira.dev>
  • Loading branch information
ebuchman and andynog authored Sep 30, 2020
1 parent 0fa2b89 commit 76e02cc
Show file tree
Hide file tree
Showing 16 changed files with 467 additions and 11 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@


# Generated by Cargo
# will have compiled files and executables
/target/
Expand All @@ -11,3 +13,6 @@ Cargo.lock

# Ignore database folders
**/*.db/

# Ignore Jetbrains
.idea
2 changes: 1 addition & 1 deletion modules/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ serde = "1.0.104"
serde_json = "1"
tracing = "0.1.13"
prost = "0.6.1"
prost-types = { version = "0.6.1" }
prost-types = "0.6.1"

bytes = "0.5.5"
dyn-clonable = "0.9.0"
Expand Down
13 changes: 8 additions & 5 deletions modules/src/ics03_connection/msgs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ pub enum ConnectionMsg {
///
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct MsgConnectionOpenInit {
connection_id: ConnectionId,
client_id: ClientId,
counterparty: Counterparty,
signer: AccountId,
pub connection_id: ConnectionId,
pub client_id: ClientId,
pub counterparty: Counterparty,
pub signer: AccountId,
}

impl MsgConnectionOpenInit {
Expand Down Expand Up @@ -141,7 +141,10 @@ impl Msg for MsgConnectionOpenInit {
}

fn get_sign_bytes(&self) -> Vec<u8> {
todo!()
let mut buf = Vec::new();
let raw_msg: RawMsgConnectionOpenInit = self.clone().into();
prost::Message::encode(&raw_msg, &mut buf).unwrap();
buf
}

fn get_signers(&self) -> Vec<AccountId> {
Expand Down
3 changes: 1 addition & 2 deletions relayer-cli/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,9 @@ mod version;

use self::{
config::ConfigCmd, light::LightCmd, listen::ListenCmd, query::QueryCmd, start::StartCmd,
version::VersionCmd,
tx::TxCmd, version::VersionCmd,
};

use crate::commands::tx::TxCmd;
use crate::config::Config;
use abscissa_core::{Command, Configurable, FrameworkError, Help, Options, Runnable};
use std::path::PathBuf;
Expand Down
17 changes: 15 additions & 2 deletions relayer-cli/src/commands/tx.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,32 @@
//! `tx` subcommand
use crate::commands::tx::client::TxCreateClientCmd;
use abscissa_core::{Command, Options, Runnable};
use abscissa_core::{Command, Help, Options, Runnable};

mod client;
mod connection;

/// `tx` subcommand
#[derive(Command, Debug, Options, Runnable)]
pub enum TxCmd {
/// The `tx raw` subcommand submits IBC transactions to a chain
/// The `help` subcommand
#[options(help = "get usage information")]
Help(Help<Self>),

/// The `tx raw` subcommand
#[options(help = "tx raw")]
Raw(TxRawCommands),
}

#[derive(Command, Debug, Options, Runnable)]
pub enum TxRawCommands {
/// The `help` subcommand
#[options(help = "get usage information")]
Help(Help<Self>),

/// The `tx raw conn-init` subcommand
#[options(help = "tx raw conn-init")]
ConnInit(connection::TxRawConnInitCmd),

/// The `tx raw client-create` subcommand submits a MsgCreateClient in a transaction to a chain
#[options(help = "tx raw create-client")]
CreateClient(TxCreateClientCmd),
Expand Down
114 changes: 114 additions & 0 deletions relayer-cli/src/commands/tx/connection.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
use crate::prelude::*;

use crate::error::{Error, Kind};
use abscissa_core::{Command, Options, Runnable};
use relayer::config::Config;
use relayer::tx::connection::{conn_init, ConnectionOpenInitOptions};

#[derive(Clone, Command, Debug, Options)]
pub struct TxRawConnInitCmd {
#[options(free, help = "identifier of the source chain")]
src_chain_id: Option<String>,

#[options(free, help = "identifier of the destination chain")]
dest_chain_id: Option<String>,

#[options(free, help = "identifier of the source client")]
src_client_id: Option<String>,

#[options(free, help = "identifier of the destination client")]
dest_client_id: Option<String>,

#[options(free, help = "identifier of the source connection")]
src_connection_id: Option<String>,

#[options(free, help = "identifier of the destination connection")]
dest_connection_id: Option<String>,
}

impl TxRawConnInitCmd {
fn validate_options(&self, config: &Config) -> Result<ConnectionOpenInitOptions, 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 src chain configuration".to_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_client_id = self
.src_client_id
.as_ref()
.ok_or_else(|| "missing source client identifier".to_string())?
.parse()
.map_err(|_| "bad source client identifier".to_string())?;

let src_connection_id = self
.src_connection_id
.as_ref()
.ok_or_else(|| "missing source connection identifier".to_string())?
.parse()
.map_err(|_| "bad source connection identifier".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 destination client identifier".to_string())?;

let dest_connection_id = self
.dest_connection_id
.as_ref()
.ok_or_else(|| "missing destination connection identifier".to_string())?
.parse()
.map_err(|_| "bad destination connection identifier".to_string())?;

let opts = ConnectionOpenInitOptions {
src_client_id,
dest_client_id,
src_connection_id,
dest_connection_id,
src_chain_config: src_chain_config.clone(),
dest_chain_config: dest_chain_config.clone(),
};

Ok(opts)
}
}

impl Runnable for TxRawConnInitCmd {
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> = conn_init(opts).map_err(|e| Kind::Tx.context(e).into());

match res {
Ok(receipt) => status_info!("conn init, result: ", "{:?}", receipt),
Err(e) => status_info!("conn init failed, error: ", "{}", e),
}
}
}
9 changes: 9 additions & 0 deletions relayer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ authors = [

[dependencies]
ibc = { path = "../modules" }
ibc-proto = "0.2.2"
tendermint = "0.15.0"
tendermint-rpc = { version = "0.15.0", features=["client"] }
tendermint-proto = "0.1.0"
Expand All @@ -27,4 +28,12 @@ bytes = "0.5.6"
prost = "0.6.1"
prost-types = { version = "0.6.1" }

# Needed for tx sign when ready in tendermint upgrade
#k256 = { version = "0.4", features = ["ecdsa-core", "ecdsa", "sha256"]}
#tendermint-rpc = "0.15"
#rust-crypto = "0.2.36"
#hex = "0.4"
#ripemd160 = { version = "0.9", optional = true }
#sha2 = { version = "0.9.1", default-features = false }

[dev-dependencies]
1 change: 1 addition & 0 deletions relayer/src/auth.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod tx;
130 changes: 130 additions & 0 deletions relayer/src/auth/tx.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
// use ibc_proto::tx::v1beta1::{Tx, TxBody, AuthInfo, SignDoc};
// use ibc::tx_msg::Msg;
//use crate::error::Error;
// use ibc_proto::tx::v1beta1::mode_info::{Single, Sum};
// use ibc_proto::tx::v1beta1::{AuthInfo, ModeInfo, SignDoc, SignerInfo, Tx, TxBody};
// use ibc::tx_msg::Msg;
// use ibc_proto::base::crypto::v1beta1::public_key::Sum as PK_Sum;
// use ibc_proto::base::crypto::v1beta1::PublicKey;
// use tendermint::{account::Id, chain::Id as ChainId, net::Address};
// use hex;
// use std::str::FromStr;
// Signer
// use k256::{
// ecdsa::{signature::Signer, signature::Verifier, Signature, SigningKey, VerifyKey},
// EncodedPoint, SecretKey,
// };

// pub struct TxWrapper {
// tx: Tx,
// body: Vec<u8>,
// auth_info: Vec<u8>,
// }

// pub struct TxBuilder {
//
// }

//impl TxBuilder {
// pub fn build_tx<T: std::error::Error, U: Msg<ValidationError = T>>(msg: Vec<Box<U>>, memo: String) -> Result<TxBody, Error> {

// Create TxBody
// let body = TxBody {
// messages: proto_msgs,
// memo: "".to_string(),
// timeout_height: 0,
// extension_options: Vec::<prost_types::Any>::new(),
// non_critical_extension_options: Vec::<prost_types::Any>::new(),
// };
//
// // A protobuf serialization of a TxBody
// let mut body_buf = Vec::new();
// prost::Message::encode(&body, &mut body_buf).unwrap();

// TODO: move this logic to tx builder
// let sum = Some(PK_Sum::Secp256k1(pubkey_bytes));
//
// let pk = Some(PublicKey { sum });
//
// let single = Single { mode: 1 };
// let sum_single = Some(Sum::Single(single));
// let mode = Some(ModeInfo { sum: sum_single });
//
// let signer_info = SignerInfo {
// public_key: pk,
// mode_info: mode,
// sequence: 0,
// };
//
// let auth_info = AuthInfo {
// signer_infos: vec![signer_info],
// fee: None,
// };
//
// // A protobuf serialization of a AuthInfo
// let mut auth_buf = Vec::new();
// prost::Message::encode(&auth_info, &mut auth_buf).unwrap();
//
// let sign_doc = SignDoc {
// body_bytes: body_buf.clone(),
// auth_info_bytes: auth_buf.clone(),
// chain_id: chain_config.clone().id.to_string(),
// account_number: account_number,
// };
//
// // A protobuf serialization of a AuthInfo
// let mut signdoc_buf = Vec::new();
// prost::Message::encode(&sign_doc, &mut signdoc_buf).unwrap();
//
// let signature: Signature = signing_key.sign(&signdoc_buf);
//
// status_info!("Signed Tx", "{:?}", signed_doc);
//
// let tx_raw = TxRaw {
// body_bytes,
// auth_info_bytes: auth_bytes,
// signatures: vec![signature.as_ref().to_vec()],
// };
//
// let mut txraw_buf = Vec::new();
// prost::Message::encode(&tx_raw, &mut txraw_buf).unwrap();
// println!("{:?}", txraw_buf);
// }

// pub fn get_sign_doc(body: TxBody, auth: AuthInfo) -> Result<SignDoc, Error> {
// // A protobuf serialization of a TxBody
// let mut body_buf = Vec::new();
// prost::Message::encode(&body, &mut body_buf).unwrap();
//
// // A protobuf serialization of a AuthInfo
// let mut auth_buf = Vec::new();
// prost::Message::encode(&auth_info, &mut auth_buf).unwrap();
//
// let sign_doc = SignDoc {
// body_bytes: body_buf.clone(),
// auth_info_bytes: auth_buf.clone(),
// chain_id: chain_config.clone().id.to_string(),
// account_number: account_number,
// };
//
// Ok(signdoc)
// }

// convenience function to get address from private key

// fn get_account(pk: Vec<u8>) -> Vec<u8> {
// use crypto::digest::Digest;
// use crypto::ripemd160::Ripemd160;
// use crypto::sha2::Sha256;
// let mut seed = Sha256::new();
// seed.input(pk.as_slice());
// let mut bytes = vec![0; seed.output_bytes()];
// seed.result(&mut bytes);
//
// let mut hash = Ripemd160::new();
// hash.input(bytes.as_slice());
// let mut acct = vec![0; hash.output_bytes()];
// hash.result(&mut acct);
// acct.to_vec()
// }
//}
4 changes: 4 additions & 0 deletions relayer/src/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ pub trait Chain {

/// The trust threshold configured for this chain
fn trust_threshold(&self) -> TrustThresholdFraction;

/// Sign message
/// TODO - waiting for tendermint-rs upgrade to v0.16
fn sign_tx(&self, _msgs: &[Any]) -> Result<Vec<u8>, Self::Error>;
}

/// Query the latest height the chain is at via a RPC query
Expand Down
Loading

0 comments on commit 76e02cc

Please sign in to comment.