From 2ad06ff9bd904582c12bf95db13ddfd59dd62b7a Mon Sep 17 00:00:00 2001 From: brentstone Date: Fri, 1 Nov 2024 16:49:26 -0700 Subject: [PATCH 1/7] derive ibc token address client util --- crates/apps_lib/src/cli.rs | 48 +++++++++++++++++++++++++++++ crates/apps_lib/src/cli/client.rs | 3 ++ crates/apps_lib/src/client/utils.rs | 9 ++++++ 3 files changed, 60 insertions(+) diff --git a/crates/apps_lib/src/cli.rs b/crates/apps_lib/src/cli.rs index 6c368ddd616..de60ad32565 100644 --- a/crates/apps_lib/src/cli.rs +++ b/crates/apps_lib/src/cli.rs @@ -2493,6 +2493,7 @@ pub mod cmds { ValidateGenesisTemplates(ValidateGenesisTemplates), SignGenesisTxs(SignGenesisTxs), ParseMigrationJson(MigrationJson), + DeriveIbcToken(DeriveIbcToken), } impl SubCmd for ClientUtils { @@ -2527,6 +2528,8 @@ pub mod cmds { SubCmd::parse(matches).map(Self::SignGenesisTxs); let parse_migrations_json = SubCmd::parse(matches).map(Self::ParseMigrationJson); + let derive_ibc_token = + SubCmd::parse(matches).map(Self::DeriveIbcToken); join_network .or(validate_wasm) .or(init_network) @@ -2541,6 +2544,7 @@ pub mod cmds { .or(genesis_tx) .or(parse_migrations_json) .or(sign_offline) + .or(derive_ibc_token) }) } @@ -2561,6 +2565,7 @@ pub mod cmds { .subcommand(ValidateGenesisTemplates::def()) .subcommand(SignGenesisTxs::def()) .subcommand(MigrationJson::def()) + .subcommand(DeriveIbcToken::def()) .subcommand_required(true) .arg_required_else_help(true) } @@ -2607,6 +2612,29 @@ pub mod cmds { } } + #[derive(Clone, Debug)] + pub struct DeriveIbcToken(pub args::DeriveIbcToken); + + impl SubCmd for DeriveIbcToken { + const CMD: &'static str = "derive-token-address"; + + fn parse(matches: &ArgMatches) -> Option { + matches + .subcommand_matches(Self::CMD) + .map(|matches| Self(args::DeriveIbcToken::parse(matches))) + } + + fn def() -> App { + App::new(Self::CMD) + .about(wrap!( + "Derive the IBC token address on Namada from the denom \ + string, typically in the form of \ + 'transfer/channel-/'." + )) + .add_args::() + } + } + #[derive(Clone, Debug)] pub struct InitNetwork(pub args::InitNetwork); @@ -3441,6 +3469,7 @@ pub mod args { pub const HISTORIC: ArgFlag = flag("historic"); pub const IBC_SHIELDING_DATA_PATH: ArgOpt = arg_opt("ibc-shielding-data"); + pub const IBC_DENOM: Arg = arg("ibc-denom"); pub const IBC_MEMO: ArgOpt = arg_opt("ibc-memo"); pub const INPUT_OPT: ArgOpt = arg_opt("input"); pub const LEDGER_ADDRESS_ABOUT: &str = textwrap_macros::fill!( @@ -8308,6 +8337,25 @@ pub mod args { } } + #[derive(Clone, Debug)] + pub struct DeriveIbcToken { + pub ibc_denom: String, + } + + impl Args for DeriveIbcToken { + fn parse(matches: &ArgMatches) -> Self { + let ibc_denom: String = IBC_DENOM.parse(matches); + Self { ibc_denom } + } + + fn def(app: App) -> App { + app.arg(IBC_DENOM.def().help(wrap!( + "The IBC token string, in the format of \ + 'transfer/channel-/" + ))) + } + } + #[derive(Clone, Debug)] pub struct InitNetwork { pub templates_path: PathBuf, diff --git a/crates/apps_lib/src/cli/client.rs b/crates/apps_lib/src/cli/client.rs index a11f6b785bc..4182e8d7426 100644 --- a/crates/apps_lib/src/cli/client.rs +++ b/crates/apps_lib/src/cli/client.rs @@ -885,6 +885,9 @@ impl CliApi { ) } } + ClientUtils::DeriveIbcToken(DeriveIbcToken(args)) => { + utils::derive_ibc_token_address(args); + } } } } diff --git a/crates/apps_lib/src/client/utils.rs b/crates/apps_lib/src/client/utils.rs index c8fa7fe6a32..26d8857a87d 100644 --- a/crates/apps_lib/src/client/utils.rs +++ b/crates/apps_lib/src/client/utils.rs @@ -14,6 +14,7 @@ use namada_sdk::address::Address; use namada_sdk::args::DeviceTransport; use namada_sdk::chain::ChainId; use namada_sdk::dec::Dec; +use namada_sdk::ibc::trace::ibc_token; use namada_sdk::key::*; use namada_sdk::string_encoding::StringEncoded; use namada_sdk::token; @@ -1164,3 +1165,11 @@ fn safe_exit(code: i32) -> ! { fn safe_exit(code: i32) -> ! { panic!("Process exited unsuccessfully with error code: {}", code); } + +/// Derive the IBC token address on namada from the denom string +pub fn derive_ibc_token_address( + args::DeriveIbcToken { ibc_denom }: args::DeriveIbcToken, +) { + let token_address = ibc_token(&ibc_denom); + println!("{token_address}"); +} From c51e419219cdfd86a78af2edeea1cdf66b311fc5 Mon Sep 17 00:00:00 2001 From: brentstone Date: Fri, 1 Nov 2024 22:07:14 -0700 Subject: [PATCH 2/7] client util: derive impl address from pubkey --- crates/apps_lib/src/cli.rs | 45 +++++++++++++++++++++++++++++ crates/apps_lib/src/cli/client.rs | 3 ++ crates/apps_lib/src/client/utils.rs | 11 ++++++- 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/crates/apps_lib/src/cli.rs b/crates/apps_lib/src/cli.rs index de60ad32565..0e1c212e256 100644 --- a/crates/apps_lib/src/cli.rs +++ b/crates/apps_lib/src/cli.rs @@ -2494,6 +2494,7 @@ pub mod cmds { SignGenesisTxs(SignGenesisTxs), ParseMigrationJson(MigrationJson), DeriveIbcToken(DeriveIbcToken), + PubKeyToAddr(PubKeyToAddr), } impl SubCmd for ClientUtils { @@ -2530,6 +2531,8 @@ pub mod cmds { SubCmd::parse(matches).map(Self::ParseMigrationJson); let derive_ibc_token = SubCmd::parse(matches).map(Self::DeriveIbcToken); + let pubkey_to_addr = + SubCmd::parse(matches).map(Self::PubKeyToAddr); join_network .or(validate_wasm) .or(init_network) @@ -2545,6 +2548,7 @@ pub mod cmds { .or(parse_migrations_json) .or(sign_offline) .or(derive_ibc_token) + .or(pubkey_to_addr) }) } @@ -2566,6 +2570,7 @@ pub mod cmds { .subcommand(SignGenesisTxs::def()) .subcommand(MigrationJson::def()) .subcommand(DeriveIbcToken::def()) + .subcommand(PubKeyToAddr::def()) .subcommand_required(true) .arg_required_else_help(true) } @@ -2635,6 +2640,28 @@ pub mod cmds { } } + #[derive(Clone, Debug)] + pub struct PubKeyToAddr(pub args::PubKeyToAddr); + + impl SubCmd for PubKeyToAddr { + const CMD: &'static str = "pubkey-to-address"; + + fn parse(matches: &ArgMatches) -> Option { + matches + .subcommand_matches(Self::CMD) + .map(|matches| Self(args::PubKeyToAddr::parse(matches))) + } + + fn def() -> App { + App::new(Self::CMD) + .about(wrap!( + "Derive the implicit address (tnam) associated with a \ + given public key (tpknam)." + )) + .add_args::() + } + } + #[derive(Clone, Debug)] pub struct InitNetwork(pub args::InitNetwork); @@ -8356,6 +8383,24 @@ pub mod args { } } + #[derive(Clone, Debug)] + pub struct PubKeyToAddr { + pub public_key: common::PublicKey, + } + + impl Args for PubKeyToAddr { + fn parse(matches: &ArgMatches) -> Self { + let public_key: common::PublicKey = RAW_PUBLIC_KEY.parse(matches); + Self { public_key } + } + + fn def(app: App) -> App { + app.arg(RAW_PUBLIC_KEY.def().help(wrap!( + "The raw public key to be converted into an implicit address" + ))) + } + } + #[derive(Clone, Debug)] pub struct InitNetwork { pub templates_path: PathBuf, diff --git a/crates/apps_lib/src/cli/client.rs b/crates/apps_lib/src/cli/client.rs index 4182e8d7426..d755c7d7f40 100644 --- a/crates/apps_lib/src/cli/client.rs +++ b/crates/apps_lib/src/cli/client.rs @@ -888,6 +888,9 @@ impl CliApi { ClientUtils::DeriveIbcToken(DeriveIbcToken(args)) => { utils::derive_ibc_token_address(args); } + ClientUtils::PubKeyToAddr(PubKeyToAddr(args)) => { + utils::pubkey_to_address(args); + } } } } diff --git a/crates/apps_lib/src/client/utils.rs b/crates/apps_lib/src/client/utils.rs index 26d8857a87d..f75bc3b6f16 100644 --- a/crates/apps_lib/src/client/utils.rs +++ b/crates/apps_lib/src/client/utils.rs @@ -10,7 +10,7 @@ use flate2::write::GzEncoder; use flate2::Compression; use itertools::Either; use namada_sdk::account::AccountPublicKeysMap; -use namada_sdk::address::Address; +use namada_sdk::address::{Address, ImplicitAddress}; use namada_sdk::args::DeviceTransport; use namada_sdk::chain::ChainId; use namada_sdk::dec::Dec; @@ -1173,3 +1173,12 @@ pub fn derive_ibc_token_address( let token_address = ibc_token(&ibc_denom); println!("{token_address}"); } + +/// Derive the implicit address from a raw public key +pub fn pubkey_to_address( + args::PubKeyToAddr { public_key }: args::PubKeyToAddr, +) { + let pkh = PublicKeyHash::from(&public_key); + let addr = Address::Implicit(ImplicitAddress(pkh.clone())); + println!("{addr}"); +} From 280638953fa54f7c190b9c9da688e93e01960a2c Mon Sep 17 00:00:00 2001 From: brentstone Date: Fri, 1 Nov 2024 22:46:41 -0700 Subject: [PATCH 3/7] changelog: add #3968 --- .../unreleased/improvements/3968-derive-ibc-token-address.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .changelog/unreleased/improvements/3968-derive-ibc-token-address.md diff --git a/.changelog/unreleased/improvements/3968-derive-ibc-token-address.md b/.changelog/unreleased/improvements/3968-derive-ibc-token-address.md new file mode 100644 index 00000000000..793ff46e967 --- /dev/null +++ b/.changelog/unreleased/improvements/3968-derive-ibc-token-address.md @@ -0,0 +1,2 @@ +- Add new useful client utilities. + ([\#3968](https://github.com/anoma/namada/pull/3968)) \ No newline at end of file From 5b138146c709dfd7d01c3f30002a9f4f0fe702ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Mon, 4 Nov 2024 14:17:25 +0100 Subject: [PATCH 4/7] deps: switch back to config-rs release --- Cargo.lock | 6 +++--- Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4e44acc96f6..1a500bf153b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1169,13 +1169,13 @@ dependencies = [ [[package]] name = "config" -version = "0.14.0" -source = "git+https://github.com/mehcode/config-rs.git?rev=e3c1d0b452639478662a44f15ef6d5b6d969bf9b#e3c1d0b452639478662a44f15ef6d5b6d969bf9b" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68578f196d2a33ff61b27fae256c3164f65e36382648e30666dde05b8cc9dfdf" dependencies = [ "async-trait", "convert_case", "json5", - "lazy_static", "nom", "pathdiff", "ron", diff --git a/Cargo.toml b/Cargo.toml index 175e27bff07..a0c6df134de 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -93,7 +93,7 @@ clap_complete_nushell = "4.5" clru = {git = "https://github.com/marmeladema/clru-rs.git", rev = "71ca566"} color-eyre = "0.6.2" concat-idents = "1.1.2" -config = { git = "https://github.com/mehcode/config-rs.git", rev = "e3c1d0b452639478662a44f15ef6d5b6d969bf9b" } +config = "0.14.1" data-encoding = "2.3.2" derivation-path = "0.2.0" derivative = "2.2.0" From a846551bbb8500062f010bb1e89e0ccfae260243 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Mon, 4 Nov 2024 14:20:23 +0100 Subject: [PATCH 5/7] apps/config: restore the prefix separator to a single underscore --- crates/apps_lib/src/config/mod.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/apps_lib/src/config/mod.rs b/crates/apps_lib/src/config/mod.rs index b60b0f494f3..ebb63b7ea35 100644 --- a/crates/apps_lib/src/config/mod.rs +++ b/crates/apps_lib/src/config/mod.rs @@ -287,7 +287,9 @@ impl Config { .add_source(defaults) .add_source(config::File::with_name(file_name)) .add_source( - config::Environment::with_prefix("NAMADA").separator("__"), + config::Environment::with_prefix("NAMADA") + .prefix_separator("_") + .separator("__"), ); let config = builder.build().map_err(Error::ReadError)?; From 1f1c27b8a171885061918d44bac492d3a5709fc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Mon, 4 Nov 2024 14:40:33 +0100 Subject: [PATCH 6/7] test/apps/config: unit test config key-val set from env var --- crates/apps_lib/src/config/mod.rs | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/crates/apps_lib/src/config/mod.rs b/crates/apps_lib/src/config/mod.rs index ebb63b7ea35..ba04f8bdb23 100644 --- a/crates/apps_lib/src/config/mod.rs +++ b/crates/apps_lib/src/config/mod.rs @@ -856,11 +856,38 @@ namespace = "cometbft" #[cfg(test)] mod tests { - use super::DEFAULT_COMETBFT_CONFIG; + use std::env; + + use namada_sdk::chain::ChainId; + use tempfile::tempdir; + + use super::{Config, DEFAULT_COMETBFT_CONFIG}; + use crate::config::TendermintMode; use crate::tendermint_config::TendermintConfig; #[test] fn test_default_cometbft_config() { assert!(TendermintConfig::parse_toml(DEFAULT_COMETBFT_CONFIG).is_ok()); } + + /// Check that a key-val set from an env var gets applied to a loaded config + #[test] + fn test_config_env_var() { + let base_dir = tempdir().unwrap(); + let chain_id = ChainId("ChainyMcChainFace".to_owned()); + + Config::generate( + base_dir.path(), + &chain_id, + TendermintMode::Full, + true, + ) + .unwrap(); + + let moniker = "moniker_from_env"; + env::set_var("NAMADA_LEDGER__COMETBFT__MONIKER", moniker); + let config = Config::load(&base_dir, &chain_id, None); + + assert_eq!(config.ledger.cometbft.moniker.as_ref(), moniker); + } } From b51078f1ed5618e852925058670438d6fa29d93d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Mon, 4 Nov 2024 15:02:57 +0100 Subject: [PATCH 7/7] changelog: add #3971 --- .changelog/unreleased/bug-fixes/3971-fix-config-from-env.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .changelog/unreleased/bug-fixes/3971-fix-config-from-env.md diff --git a/.changelog/unreleased/bug-fixes/3971-fix-config-from-env.md b/.changelog/unreleased/bug-fixes/3971-fix-config-from-env.md new file mode 100644 index 00000000000..402ddf3a604 --- /dev/null +++ b/.changelog/unreleased/bug-fixes/3971-fix-config-from-env.md @@ -0,0 +1,3 @@ +- Fix the prefix separator for config key-vals set from env var to a + single underscore between the "NAMADA" prefix and the rest of the path. + ([\#3971](https://github.com/anoma/namada/pull/3971)) \ No newline at end of file