From 0a270e2f1838ad9c41d068c81eafb749f91da6dc Mon Sep 17 00:00:00 2001 From: Jeongseup Date: Fri, 2 Feb 2024 20:01:35 +0900 Subject: [PATCH 1/3] Add a new cli 'wallet convert' for coverting tendermnint key json file with consesus key in wallet.toml --- crates/apps/src/lib/cli.rs | 38 +++++++++++++++++++ crates/apps/src/lib/cli/wallet.rs | 23 +++++++++++ .../src/lib/node/ledger/tendermint_node.rs | 4 +- crates/sdk/src/args.rs | 7 ++++ 4 files changed, 70 insertions(+), 2 deletions(-) diff --git a/crates/apps/src/lib/cli.rs b/crates/apps/src/lib/cli.rs index 8cb65ebcd5..e55f7eb398 100644 --- a/crates/apps/src/lib/cli.rs +++ b/crates/apps/src/lib/cli.rs @@ -501,6 +501,8 @@ pub mod cmds { KeyAddrFind(WalletFindKeysAddresses), /// Key export KeyExport(WalletExportKey), + /// Key convert + KeyConvert(WalletConvertKey), /// Key import KeyImport(WalletImportKey), /// Key / address add @@ -517,6 +519,7 @@ pub mod cmds { .subcommand(WalletListKeysAddresses::def()) .subcommand(WalletFindKeysAddresses::def()) .subcommand(WalletExportKey::def()) + .subcommand(WalletConvertKey::def()) .subcommand(WalletImportKey::def()) .subcommand(WalletAddKeyAddress::def()) .subcommand(WalletRemoveKeyAddress::def()) @@ -529,6 +532,7 @@ pub mod cmds { let key_addr_list = SubCmd::parse(matches).map(Self::KeyAddrList); let key_addr_find = SubCmd::parse(matches).map(Self::KeyAddrFind); let export = SubCmd::parse(matches).map(Self::KeyExport); + let convert = SubCmd::parse(matches).map(Self::KeyConvert); let import = SubCmd::parse(matches).map(Self::KeyImport); let key_addr_add = SubCmd::parse(matches).map(Self::KeyAddrAdd); let key_addr_remove = @@ -538,6 +542,7 @@ pub mod cmds { .or(key_addr_list) .or(key_addr_find) .or(export) + .or(convert) .or(import) .or(key_addr_add) .or(key_addr_remove) @@ -704,6 +709,26 @@ pub mod cmds { } } + /// Export key to a file + #[derive(Clone, Debug)] + pub struct WalletConvertKey(pub args::KeyConvert); + + impl SubCmd for WalletConvertKey { + const CMD: &'static str = "convert"; + + fn parse(matches: &ArgMatches) -> Option { + matches + .subcommand_matches(Self::CMD) + .map(|matches| (Self(args::KeyConvert::parse(matches)))) + } + + fn def() -> App { + App::new(Self::CMD) + .about("Convert to tendermint priv_validator_key.json with your consensus key alias") + .add_args::() + } + } + /// Import key from a file #[derive(Clone, Debug)] pub struct WalletImportKey(pub args::KeyImport); @@ -6582,6 +6607,19 @@ pub mod args { } } + impl Args for KeyConvert { + fn parse(matches: &ArgMatches) -> Self { + let alias = ALIAS.parse(matches); + Self { alias } + } + + fn def(app: App) -> App { + app.arg( + ALIAS.def().help("The alias of the key you wish to export."), + ) + } + } + impl Args for KeyImport { fn parse(matches: &ArgMatches) -> Self { let file_path = FILE_PATH.parse(matches); diff --git a/crates/apps/src/lib/cli/wallet.rs b/crates/apps/src/lib/cli/wallet.rs index 3ce69521e4..aa1d93d66c 100644 --- a/crates/apps/src/lib/cli/wallet.rs +++ b/crates/apps/src/lib/cli/wallet.rs @@ -28,6 +28,7 @@ use crate::cli::api::CliApi; use crate::cli::args::CliToSdk; use crate::cli::{args, cmds, Context}; use crate::client::utils::PRE_GENESIS_DIR; +use crate::node::ledger::tendermint_node::validator_key_to_json; use crate::wallet::{ self, read_and_confirm_encryption_password, CliWalletUtils, }; @@ -54,6 +55,9 @@ impl CliApi { cmds::NamadaWallet::KeyExport(cmds::WalletExportKey(args)) => { key_export(ctx, io, args) } + cmds::NamadaWallet::KeyConvert(cmds::WalletConvertKey(args)) => { + key_convert(ctx, io, args) + } cmds::NamadaWallet::KeyImport(cmds::WalletImportKey(args)) => { key_import(ctx, io, args) } @@ -1243,6 +1247,25 @@ fn key_export( }) } +/// Convert a consensus key to tendermint validator key in json format +fn key_convert( + ctx: Context, + io: &impl Io, + args::KeyConvert { alias }: args::KeyConvert, +) { + let alias = alias.to_lowercase(); + let mut wallet = load_wallet(ctx); + let sk = wallet.find_secret_key(&alias, None); + let key: serde_json::Value = validator_key_to_json(&sk.unwrap()).unwrap(); + let file_name = format!("priv_validator_key.json_{}", alias); + let file = File::create(&file_name).unwrap(); + serde_json::to_writer_pretty(file, &key).unwrap_or_else(|err| { + edisplay_line!(io, "{}", err); + cli::safe_exit(1) + }); + display_line!(io, "Converted to file {}", file_name); +} + /// Import a transparent keypair / MASP spending key from a file. fn key_import( ctx: Context, diff --git a/crates/apps/src/lib/node/ledger/tendermint_node.rs b/crates/apps/src/lib/node/ledger/tendermint_node.rs index 87616d9df2..9efd96de5e 100644 --- a/crates/apps/src/lib/node/ledger/tendermint_node.rs +++ b/crates/apps/src/lib/node/ledger/tendermint_node.rs @@ -261,7 +261,7 @@ pub fn rollback(tendermint_dir: impl AsRef) -> Result { /// Convert a common signing scheme validator key into JSON for /// Tendermint -fn validator_key_to_json( +pub fn validator_key_to_json( sk: &common::SecretKey, ) -> std::result::Result { let raw_hash = tm_consensus_key_raw_hash(&sk.ref_to()); @@ -316,7 +316,7 @@ pub fn write_validator_state(home_dir: impl AsRef) -> Result<()> { } /// Abstract over the initialization of validator data for Tendermint -fn write_validator( +pub fn write_validator( path: PathBuf, err_dir: &'static str, err_file: &'static str, diff --git a/crates/sdk/src/args.rs b/crates/sdk/src/args.rs index e8d2cbcdd2..a5d2312c43 100644 --- a/crates/sdk/src/args.rs +++ b/crates/sdk/src/args.rs @@ -2173,6 +2173,13 @@ pub struct KeyExport { pub alias: String, } +/// Wallet key export arguments +#[derive(Clone, Debug)] +pub struct KeyConvert { + /// Key alias + pub alias: String, +} + /// Wallet key import arguments #[derive(Clone, Debug)] pub struct KeyImport { From 0813ae4f85619674795d46ff64da0de0578c43af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Thu, 15 Feb 2024 12:26:45 +0000 Subject: [PATCH 2/3] make fmt --- crates/apps/src/lib/cli.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/crates/apps/src/lib/cli.rs b/crates/apps/src/lib/cli.rs index e55f7eb398..353ebf79a0 100644 --- a/crates/apps/src/lib/cli.rs +++ b/crates/apps/src/lib/cli.rs @@ -724,7 +724,10 @@ pub mod cmds { fn def() -> App { App::new(Self::CMD) - .about("Convert to tendermint priv_validator_key.json with your consensus key alias") + .about( + "Convert to tendermint priv_validator_key.json with your \ + consensus key alias", + ) .add_args::() } } From 510fc856f1527f9a867d0c2299231ef0d75d353d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Thu, 15 Feb 2024 12:26:51 +0000 Subject: [PATCH 3/3] changelog: add #2516 --- .changelog/unreleased/features/2516-consensus-key-to-tm-key.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/unreleased/features/2516-consensus-key-to-tm-key.md diff --git a/.changelog/unreleased/features/2516-consensus-key-to-tm-key.md b/.changelog/unreleased/features/2516-consensus-key-to-tm-key.md new file mode 100644 index 0000000000..ee369b82bf --- /dev/null +++ b/.changelog/unreleased/features/2516-consensus-key-to-tm-key.md @@ -0,0 +1,3 @@ +- Added wallet command to "convert" a consensus key + into Tendermint private validator key JSON format. + ([\#2516](https://github.com/anoma/namada/pull/2516)) \ No newline at end of file