Skip to content

Commit

Permalink
Merge pull request #3660 from anoma/tomas/check-pre-genesis-signing
Browse files Browse the repository at this point in the history
check pre genesis signing
  • Loading branch information
mergify[bot] committed Aug 16, 2024
2 parents 7e9239d + 8c97cc5 commit d5fbd97
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
- The command `namadan utils test-genesis` now accepts `--check-can-sign`
multi-arg that can be used with genesis addresses and/or public keys to
verify that a pre-genesis wallet in the base directory is able to sign
with the keys associated with the addresses or with the keys themselves.
([\#3660](https://github.com/anoma/namada/pull/3660))
4 changes: 2 additions & 2 deletions crates/apps/src/bin/namada-node/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,9 +166,9 @@ pub fn main() -> Result<()> {
std::fs::write(config_path, updated_config).unwrap();
}
},
cli::NamadaNode::Utils(sub, _global_args) => match sub {
cli::NamadaNode::Utils(sub, global_args) => match sub {
cmds::NodeUtils::TestGenesis(TestGenesis(args)) => {
node::utils::test_genesis(args)
node::utils::test_genesis(args, global_args)
}
},
}
Expand Down
15 changes: 14 additions & 1 deletion crates/apps_lib/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3338,6 +3338,8 @@ pub mod args {
scheme is not supplied, it is assumed to be TCP.",
60
);
pub const CHECK_CAN_SIGN: ArgMulti<AddrOrPk, GlobStar> =
arg_multi("check-can-sign");
pub const CONFIG_RPC_LEDGER_ADDRESS: ArgDefaultFromCtx<ConfigRpcAddress> =
arg_default_from_ctx("node", DefaultFn(|| "".to_string()));

Expand Down Expand Up @@ -8230,13 +8232,19 @@ pub mod args {
/// Templates dir
pub path: PathBuf,
pub wasm_dir: PathBuf,
pub check_can_sign: Vec<AddrOrPk>,
}

impl Args for TestGenesis {
fn parse(matches: &ArgMatches) -> Self {
let path = PATH.parse(matches);
let wasm_dir = WASM_DIR.parse(matches).unwrap_or_default();
Self { path, wasm_dir }
let check_can_sign = CHECK_CAN_SIGN.parse(matches);
Self {
path,
wasm_dir,
check_can_sign,
}
}

fn def(app: App) -> App {
Expand All @@ -8249,6 +8257,11 @@ pub mod args {
"Optional wasm directory to provide as part of verifying \
genesis template files"
)))
.arg(CHECK_CAN_SIGN.def().help(wrap!(
"Check that the pre-genesis wallet is able to sign with the \
given keys and/or keys associated with the given addresses. \
A pre-genesis wallet must be present in the base directory."
)))
}
}

Expand Down
121 changes: 115 additions & 6 deletions crates/node/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,24 @@

use std::str::FromStr;

use namada_apps_lib::cli::args::TestGenesis;
use namada_apps_lib::config::genesis;
use namada_apps_lib::cli::args::{self, TestGenesis};
use namada_apps_lib::client::utils::PRE_GENESIS_DIR;
use namada_apps_lib::config::genesis::{self, AddrOrPk};
use namada_apps_lib::{cli, wallet};
use namada_sdk::address::{Address, ImplicitAddress};
use namada_sdk::key::common;
use namada_sdk::wallet::FindKeyError;

pub fn test_genesis(args: TestGenesis) {
use crate::facade::tendermint::Timeout;
use crate::facade::tendermint::Timeout;

let templates = genesis::templates::load_and_validate(&args.path).unwrap();
pub fn test_genesis(args: TestGenesis, global_args: args::Global) {
let TestGenesis {
path,
wasm_dir,
check_can_sign,
} = args;

let templates = genesis::templates::load_and_validate(&path).unwrap();
let genesis = genesis::chain::finalize(
templates,
FromStr::from_str("namada-dryrun").unwrap(),
Expand All @@ -21,5 +32,103 @@ pub fn test_genesis(args: TestGenesis) {
genesis
.write_toml_files(&test_dir.path().join(chain_id.to_string()))
.unwrap();
crate::test_genesis_files(config.ledger, genesis, args.wasm_dir);
crate::test_genesis_files(config.ledger, genesis.clone(), wasm_dir);

if !check_can_sign.is_empty() {
let wallet_path = global_args.base_dir.join(PRE_GENESIS_DIR);
let mut wallet = if wallet::exists(&wallet_path) {
wallet::load(&wallet_path).unwrap()
} else {
panic!(
"Could not find wallet at {}.",
wallet_path.to_string_lossy()
);
};

let mut all_valid = true;

type WalletRes = Result<common::SecretKey, FindKeyError>;
let handle_wallet_result =
|searched: String, result: WalletRes| match result {
Ok(_) => {
println!("Able to sign with {searched}");
true
}
Err(err) => {
eprintln!("Unable to sign with {searched}. {err}");
false
}
};

for addr_or_pk in check_can_sign {
match &addr_or_pk {
AddrOrPk::PublicKey(pk) => {
if !handle_wallet_result(
pk.to_string(),
wallet.find_key_by_pk(&pk.raw, None),
) {
all_valid = false;
}
}
AddrOrPk::Address(addr) => {
match &addr {
Address::Established(_) => {
// Find PK(s) of the address in genesis
if let Some(txs) = genesis
.transactions
.established_account
.as_ref()
{
if let Some(tx) =
txs.iter().find(|tx| &tx.address == addr)
{
println!(
"Found a matching genesis established \
account tx with {} public key(s).",
tx.tx.public_keys.len()
);
for pk in &tx.tx.public_keys {
if !handle_wallet_result(
format!("{pk} for {addr}"),
wallet
.find_key_by_pk(&pk.raw, None),
) {
all_valid = false;
}
}
} else {
eprintln!(
"No genesis established account txs \
with a matching address {addr} found"
);
all_valid = false;
}
} else {
eprintln!(
"No genesis established account txs \
found. Cannot check address {addr}."
);
all_valid = false;
}
}
Address::Implicit(ImplicitAddress(pkh)) => {
if !handle_wallet_result(
addr.to_string(),
wallet.find_key_by_pkh(pkh, None),
) {
all_valid = false;
}
}
Address::Internal(_) => {
eprintln!("Unexpected internal address {addr}");
all_valid = false;
}
}
}
}
}
if !all_valid {
cli::safe_exit(1);
}
}
}
27 changes: 25 additions & 2 deletions crates/tests/src/e2e/ledger_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use std::time::{Duration, Instant};
use color_eyre::eyre::Result;
use color_eyre::owo_colors::OwoColorize;
use namada_apps_lib::cli::context::ENV_VAR_CHAIN_ID;
use namada_apps_lib::client::utils::PRE_GENESIS_DIR;
use namada_apps_lib::config::utils::convert_tm_addr_to_socket_addr;
use namada_apps_lib::config::{self, ethereum_bridge};
use namada_apps_lib::facade::tendermint_config::net::Address as TendermintAddress;
Expand Down Expand Up @@ -2562,10 +2563,22 @@ fn masp_txs_and_queries() -> Result<()> {
#[test]
fn test_localnet_genesis() -> Result<()> {
let loc = format!("{}:{}", std::file!(), std::line!());
let dir = setup::TestDir::new();
let base_dir = setup::TestDir::new();
let working_dir = working_dir();
let genesis_path = wallet::defaults::derive_template_dir(&working_dir);
let wasm_dir = working_dir.join(config::DEFAULT_WASM_DIR);

// Path to the localnet "pre-genesis" wallet
let pre_genesis_wallet = genesis_path
.join("src")
.join(PRE_GENESIS_DIR)
.join("wallet.toml");
// Copy the pre-genesis wallet into the base-dir
let base_pre_genesis = base_dir.path().join(PRE_GENESIS_DIR);
std::fs::create_dir(&base_pre_genesis).unwrap();
std::fs::copy(pre_genesis_wallet, base_pre_genesis.join("wallet.toml"))
.unwrap();

let mut test_genesis_result = setup::run_cmd(
Bin::Node,
[
Expand All @@ -2575,13 +2588,23 @@ fn test_localnet_genesis() -> Result<()> {
&genesis_path.to_string_lossy(),
"--wasm-dir",
&wasm_dir.to_string_lossy(),
"--check-can-sign",
// Albert established addr (from `genesis/localnet/balances.toml`)
"tnam1qxfj3sf6a0meahdu9t6znp05g8zx4dkjtgyn9gfu",
// Daewon implicit addr (from `genesis/localnet/balances.toml`)
"tnam1qpca48f45pdtpcz06rue7k4kfdcjrvrux5cr3pwn",
// Validator account key (from `genesis/localnet/transactions.toml`)
"tpknam1qpg2tsrplvhu3fd7z7tq5ztc2ne3s7e2ahjl2a2cddufrzdyr752g666ytj",
],
Some(30),
&working_dir,
dir.path(),
&base_dir,
loc,
)?;
test_genesis_result
.exp_string("Genesis files were dry-run successfully")?;
test_genesis_result.exp_string("Able to sign with")?;
test_genesis_result.exp_string("Able to sign with")?;
test_genesis_result.exp_string("Able to sign with")?;
Ok(())
}

0 comments on commit d5fbd97

Please sign in to comment.