From e60fa7c0ac25e59eeba0982c2242c0bb26a43558 Mon Sep 17 00:00:00 2001 From: Andy Nogueira Date: Tue, 17 Nov 2020 17:48:02 -0500 Subject: [PATCH] Added logic to persist key seed in 'home' folder (#363) --- relayer-cli/src/commands/query/channel.rs | 2 +- relayer-cli/src/commands/query/client.rs | 4 +- relayer-cli/src/commands/query/connection.rs | 2 +- relayer-cli/tests/fixtures/two_chains.toml | 4 +- relayer/Cargo.toml | 1 + relayer/src/keys/add.rs | 51 +++++++++++++++----- 6 files changed, 47 insertions(+), 17 deletions(-) diff --git a/relayer-cli/src/commands/query/channel.rs b/relayer-cli/src/commands/query/channel.rs index aee3d1ca09..2a748cac07 100644 --- a/relayer-cli/src/commands/query/channel.rs +++ b/relayer-cli/src/commands/query/channel.rs @@ -121,7 +121,7 @@ mod tests { #[test] fn parse_channel_query_end_parameters() { let default_params = QueryChannelEndCmd { - chain_id: Some("ibc0".to_string().parse().unwrap()), + chain_id: Some("ibc-0".to_string().parse().unwrap()), port_id: Some("transfer".to_string().parse().unwrap()), channel_id: Some("testchannel".to_string().parse().unwrap()), height: None, diff --git a/relayer-cli/src/commands/query/client.rs b/relayer-cli/src/commands/query/client.rs index 20ec1dc53d..96327a7994 100644 --- a/relayer-cli/src/commands/query/client.rs +++ b/relayer-cli/src/commands/query/client.rs @@ -308,7 +308,7 @@ mod tests { #[test] fn parse_query_state_parameters() { let default_params = QueryClientStateCmd { - chain_id: Some("ibc0".to_string().parse().unwrap()), + chain_id: Some("ibc-0".to_string().parse().unwrap()), client_id: Some("ibconeclient".to_string().parse().unwrap()), height: None, proof: None, @@ -394,7 +394,7 @@ mod tests { #[test] fn parse_query_client_connections_parameters() { let default_params = QueryClientConnectionsCmd { - chain_id: Some("ibc0".to_string().parse().unwrap()), + chain_id: Some("ibc-0".to_string().parse().unwrap()), client_id: Some("clientidone".to_string().parse().unwrap()), height: Some(4), }; diff --git a/relayer-cli/src/commands/query/connection.rs b/relayer-cli/src/commands/query/connection.rs index 6ce3ab02de..3818c8eae6 100644 --- a/relayer-cli/src/commands/query/connection.rs +++ b/relayer-cli/src/commands/query/connection.rs @@ -102,7 +102,7 @@ mod tests { #[test] fn parse_connection_query_end_parameters() { let default_params = QueryConnectionEndCmd { - chain_id: Some("ibc0".to_string().parse().unwrap()), + chain_id: Some("ibc-0".to_string().parse().unwrap()), connection_id: Some("ibconeconnection".to_string().parse().unwrap()), height: None, proof: None, diff --git a/relayer-cli/tests/fixtures/two_chains.toml b/relayer-cli/tests/fixtures/two_chains.toml index ee2edb0037..13eaa3a3a6 100644 --- a/relayer-cli/tests/fixtures/two_chains.toml +++ b/relayer-cli/tests/fixtures/two_chains.toml @@ -3,7 +3,7 @@ timeout = '10s' strategy = 'naive' [[chains]] -id = 'ibc0' +id = 'ibc-0' rpc_addr = 'tcp://localhost:26657' grpc_addr = 'tcp://localhost:9090' account_prefix = 'cosmos' @@ -31,7 +31,7 @@ trusted_header_hash = '169F8F6318B8FAABDBA128AD1689E238566B69DDBD2B36F1911C0DFCA trusted_height = '7806' [[chains]] -id = 'ibc1' +id = 'ibc-1' rpc_addr = 'tcp://localhost:26557' grpc_addr = 'tcp://localhost:9091' account_prefix = 'cosmos' diff --git a/relayer/Cargo.toml b/relayer/Cargo.toml index 9b6aa8e6d5..e0f3c50ea3 100644 --- a/relayer/Cargo.toml +++ b/relayer/Cargo.toml @@ -35,6 +35,7 @@ hdpath = { version = "0.6.0", features = ["with-bitcoin"] } rust-crypto = "0.2.36" bech32 = "0.7.2" tonic = "0.3.1" +dirs = "3.0.1" [dependencies.tendermint] version = "0.17.0-rc1" diff --git a/relayer/src/keys/add.rs b/relayer/src/keys/add.rs index c8b70c0720..89424acd3c 100644 --- a/relayer/src/keys/add.rs +++ b/relayer/src/keys/add.rs @@ -1,11 +1,17 @@ -use crate::chain::CosmosSDKChain; +use crate::chain::{Chain, CosmosSDKChain}; use crate::config::ChainConfig; use crate::error; use crate::error::{Error, Kind}; use crate::keyring::store::{KeyRing, KeyRingOperations}; use futures::AsyncReadExt; use std::fs; -use std::path::Path; +use std::fs::File; +use std::io::Write; +use std::path::{Path, PathBuf}; + +pub const KEYSTORE_HOME_FOLER: &str = ".rrly/keys/"; +pub const KEYSTORE_BACKEND: &str = "keyring-test"; +pub const KEYSTORE_FILE_EXTENSION: &str = "info"; #[derive(Clone, Debug)] pub struct KeysAddOptions { @@ -15,21 +21,28 @@ pub struct KeysAddOptions { } pub fn add_key(opts: KeysAddOptions) -> Result { - // TODO - Implement the logic to persist the key in the filesystem // Get the destination chain let mut chain = CosmosSDKChain::from_config(opts.clone().chain_config)?; - let file = Path::new(&opts.file); + let keys_folder = get_keys_folder(chain.config().id.clone().as_str()) + .map_err(|e| Kind::KeyBase.context(format!("failed to create keys folder: {:?}", e)))?; - if !file.exists() { - return Err(Kind::Store - .context("cannot find key file specified".to_string()) - .into()); - } + // Create keys folder if it does not exist + fs::create_dir_all(keys_folder.clone()) + .map_err(|e| Kind::KeyBase.context("error creating keys folder"))?; - let key_file_contents = fs::read_to_string(&file) + let key_file_contents = fs::read_to_string(&opts.file) .map_err(|e| Kind::KeyBase.context("error reading the key file"))?; + // Save file to appropriate location in the keys folder + let mut filename = Path::new(keys_folder.as_os_str()).join(chain.config().key_name.as_str()); + filename.set_extension(KEYSTORE_FILE_EXTENSION); + + let mut file = + File::create(filename).map_err(|e| Kind::KeyBase.context("error creating the key file"))?; + file.write_all(&key_file_contents.as_bytes()) + .map_err(|e| Kind::KeyBase.context("error writing the key file"))?; + let key_entry = chain.keybase.key_from_seed_file(&key_file_contents); match key_entry { @@ -39,7 +52,7 @@ pub fn add_key(opts: KeysAddOptions) -> Result { .add(opts.name.clone(), k.clone()) .map_err(|e| error::Kind::KeyBase.context(e))?; Ok(format!( - "Added {} key - Account: {}", + "Added key: {} ({})", opts.name.as_str(), k.account.as_str() )) @@ -47,3 +60,19 @@ pub fn add_key(opts: KeysAddOptions) -> Result { Err(e) => Err(Kind::KeyBase.context(e).into()), } } + +fn get_keys_folder(chain: &str) -> Result { + let home = dirs::home_dir(); + match home { + Some(h) => { + let folder = Path::new(h.as_path()) + .join(KEYSTORE_HOME_FOLER) + .join(chain) + .join(KEYSTORE_BACKEND); + Ok(folder) + } + None => Err(Into::::into( + Kind::Config.context("cannot retrieve home folder"), + )), + } +}