diff --git a/.changelog/unreleased/testing/2218-update-consensus-key-change.md b/.changelog/unreleased/testing/2218-update-consensus-key-change.md new file mode 100644 index 0000000000..6c6daba7b8 --- /dev/null +++ b/.changelog/unreleased/testing/2218-update-consensus-key-change.md @@ -0,0 +1,2 @@ +- Added e2e test for change-consensus-key command. + ([\#2218](https://github.com/anoma/namada/pull/2218)) \ No newline at end of file diff --git a/.github/workflows/scripts/e2e.json b/.github/workflows/scripts/e2e.json index 6e736d16f1..8817c9b6d7 100644 --- a/.github/workflows/scripts/e2e.json +++ b/.github/workflows/scripts/e2e.json @@ -27,6 +27,7 @@ "e2e::ledger_tests::test_bond_queries": 95, "e2e::ledger_tests::suspend_ledger": 30, "e2e::ledger_tests::stop_ledger_at_height": 18, + "e2e::ledger_tests::change_consensus_key": 91, "e2e::wallet_tests::wallet_address_cmds": 1, "e2e::wallet_tests::wallet_encrypted_key_cmds": 1, "e2e::wallet_tests::wallet_encrypted_key_cmds_env_var": 1, diff --git a/apps/src/lib/cli.rs b/apps/src/lib/cli.rs index b912206519..93791f9c69 100644 --- a/apps/src/lib/cli.rs +++ b/apps/src/lib/cli.rs @@ -5416,6 +5416,7 @@ pub mod args { tx, validator: chain_ctx.get(&self.validator), consensus_key: self.consensus_key.map(|x| chain_ctx.get(&x)), + unsafe_dont_encrypt: self.unsafe_dont_encrypt, tx_code_path: self.tx_code_path.to_path_buf(), } } @@ -5426,11 +5427,13 @@ pub mod args { let tx = Tx::parse(matches); let validator = VALIDATOR.parse(matches); let consensus_key = VALIDATOR_CONSENSUS_KEY.parse(matches); + let unsafe_dont_encrypt = UNSAFE_DONT_ENCRYPT.parse(matches); let tx_code_path = PathBuf::from(TX_CHANGE_CONSENSUS_KEY_WASM); Self { tx, validator, consensus_key, + unsafe_dont_encrypt, tx_code_path, } } @@ -5444,6 +5447,10 @@ pub mod args { "The desired new consensus key. A new one will be \ generated if none given. Note this key must be ed25519.", )) + .arg(UNSAFE_DONT_ENCRYPT.def().help( + "UNSAFE: Do not encrypt the generated keypairs. Do not \ + use this for keys used in a live network.", + )) } } diff --git a/apps/src/lib/client/tx.rs b/apps/src/lib/client/tx.rs index a53f46355e..42df7b102f 100644 --- a/apps/src/lib/client/tx.rs +++ b/apps/src/lib/client/tx.rs @@ -13,6 +13,7 @@ use namada::core::ledger::governance::cli::offline::{ use namada::core::ledger::governance::cli::onchain::{ DefaultProposal, PgfFundingProposal, PgfStewardProposal, ProposalVote, }; +use namada::core::ledger::storage::EPOCH_SWITCH_BLOCKS_DELAY; use namada::ibc::apps::transfer::types::Memo; use namada::proto::{CompressedSignature, Section, Signer, Tx}; use namada::types::address::{Address, ImplicitAddress}; @@ -323,6 +324,7 @@ pub async fn submit_change_consensus_key( tx: tx_args, validator, consensus_key, + unsafe_dont_encrypt, tx_code_path: _, }: args::ConsensusKeyChange, ) -> Result<(), error::Error> { @@ -334,12 +336,8 @@ pub async fn submit_change_consensus_key( ..tx_args.clone() }; - // TODO: do I need to get the validator alias from somewhere, if it exists? - // // Don't think I should generate a new one... Should get the alias - // for the consensus key though... - - let wallet = namada.wallet().await; - + // Determine the alias for the new key + let mut wallet = namada.wallet_mut().await; let alias = wallet.find_alias(&validator).cloned(); let base_consensus_key_alias = alias .map(|al| validator_consensus_key(&al)) @@ -355,8 +353,8 @@ pub async fn submit_change_consensus_key( format!("{base_consensus_key_alias}-{key_counter}"); } - let mut wallet = namada.wallet_mut().await; - let consensus_key = consensus_key + // Check the given key or generate a new one + let new_key = consensus_key .map(|key| match key { common::PublicKey::Ed25519(_) => key, common::PublicKey::Secp256k1(_) => { @@ -369,7 +367,8 @@ pub async fn submit_change_consensus_key( }) .unwrap_or_else(|| { display_line!(namada.io(), "Generating new consensus key..."); - let password = read_and_confirm_encryption_password(false); + let password = + read_and_confirm_encryption_password(unsafe_dont_encrypt); wallet .gen_store_secret_key( // Note that TM only allows ed25519 for consensus key @@ -389,9 +388,8 @@ pub async fn submit_change_consensus_key( // Check that the new consensus key is unique let consensus_keys = rpc::query_consensus_keys(namada.client()).await; - let new_ck = consensus_key; - if consensus_keys.contains(&new_ck) { - edisplay_line!(namada.io(), "Consensus key can only be ed25519"); + if consensus_keys.contains(&new_key) { + edisplay_line!(namada.io(), "The consensus key is already being used."); safe_exit(1) } @@ -405,7 +403,7 @@ pub async fn submit_change_consensus_key( let data = ConsensusKeyChange { validator: validator.clone(), - consensus_key: new_ck, + consensus_key: new_key.clone(), }; tx.add_code_from_hash( @@ -413,7 +411,9 @@ pub async fn submit_change_consensus_key( Some(args::TX_CHANGE_CONSENSUS_KEY_WASM.to_string()), ) .add_data(data); - let signing_data = aux_signing_data(namada, &tx_args, None, None).await?; + + let signing_data = + init_validator_signing_data(namada, &tx_args, vec![new_key]).await?; tx::prepare_tx( namada, @@ -437,17 +437,14 @@ pub async fn submit_change_consensus_key( .save() .unwrap_or_else(|err| edisplay_line!(namada.io(), "{}", err)); - // let tendermint_home = config.ledger.cometbft_dir(); - // tendermint_node::write_validator_key( - // &tendermint_home, - // &consensus_key, - // ); - // tendermint_node::write_validator_state(tendermint_home); - display_line!( namada.io(), - " Consensus key \"{}\"", - consensus_key_alias + "New consensus key stored with alias \ + \"{consensus_key_alias}\". It will become active \ + {EPOCH_SWITCH_BLOCKS_DELAY} blocks before pipeline offset \ + from the current epoch, at which point you'll need to give \ + the new key to CometBFT in order to be able to sign with it \ + in consensus.", ); } else { display_line!( diff --git a/benches/txs.rs b/benches/txs.rs index 454b50f401..e19c79de4d 100644 --- a/benches/txs.rs +++ b/benches/txs.rs @@ -686,21 +686,21 @@ fn change_validator_commission(c: &mut Criterion) { fn change_consensus_key(c: &mut Criterion) { let mut csprng = rand::rngs::OsRng {}; - let consensus_key = ed25519::SigScheme::generate(&mut csprng) + let consensus_sk = ed25519::SigScheme::generate(&mut csprng) .try_to_sk::() - .unwrap() - .to_public(); + .unwrap(); + let consensus_pk = consensus_sk.to_public(); let shell = BenchShell::default(); let signed_tx = shell.generate_tx( TX_CHANGE_CONSENSUS_KEY_WASM, ConsensusKeyChange { validator: defaults::validator_address(), - consensus_key, + consensus_key: consensus_pk, }, None, None, - vec![&defaults::validator_keypair()], + vec![&defaults::validator_keypair(), &consensus_sk], ); c.bench_function("change_consensus_key", |b| { diff --git a/sdk/src/args.rs b/sdk/src/args.rs index 86a489cf7f..f2ee69abc5 100644 --- a/sdk/src/args.rs +++ b/sdk/src/args.rs @@ -1400,6 +1400,8 @@ pub struct ConsensusKeyChange { pub validator: C::Address, /// New consensus key pub consensus_key: Option, + /// Don't encrypt the keypair + pub unsafe_dont_encrypt: bool, /// Path to the TX WASM code file pub tx_code_path: PathBuf, } diff --git a/sdk/src/lib.rs b/sdk/src/lib.rs index e8ce43ae27..873e36c768 100644 --- a/sdk/src/lib.rs +++ b/sdk/src/lib.rs @@ -331,6 +331,7 @@ pub trait Namada: Sized + MaybeSync + MaybeSend { validator, consensus_key: None, tx_code_path: PathBuf::from(TX_CHANGE_CONSENSUS_KEY_WASM), + unsafe_dont_encrypt: false, tx: self.tx_builder(), } } diff --git a/test_fixtures/masp_proofs/15532D31AA5AD33E5557378544DE72EFEA51E775954A8230E3ADD9CDB4E75B23.bin b/test_fixtures/masp_proofs/15532D31AA5AD33E5557378544DE72EFEA51E775954A8230E3ADD9CDB4E75B23.bin index 7a53c6bb8b..7d6cebc551 100644 Binary files a/test_fixtures/masp_proofs/15532D31AA5AD33E5557378544DE72EFEA51E775954A8230E3ADD9CDB4E75B23.bin and b/test_fixtures/masp_proofs/15532D31AA5AD33E5557378544DE72EFEA51E775954A8230E3ADD9CDB4E75B23.bin differ diff --git a/test_fixtures/masp_proofs/30E148B3F9E8D21A41ABB09756027024E9AC79985302DD15C96CB57743A74CC3.bin b/test_fixtures/masp_proofs/30E148B3F9E8D21A41ABB09756027024E9AC79985302DD15C96CB57743A74CC3.bin index a518d5a8f3..b4d473fb25 100644 Binary files a/test_fixtures/masp_proofs/30E148B3F9E8D21A41ABB09756027024E9AC79985302DD15C96CB57743A74CC3.bin and b/test_fixtures/masp_proofs/30E148B3F9E8D21A41ABB09756027024E9AC79985302DD15C96CB57743A74CC3.bin differ diff --git a/test_fixtures/masp_proofs/473EDF0B2908F047110AC52C7F7ECD8CFD237A237C63AA565FC44893414EE7FC.bin b/test_fixtures/masp_proofs/473EDF0B2908F047110AC52C7F7ECD8CFD237A237C63AA565FC44893414EE7FC.bin index 48b5715f13..214378379e 100644 Binary files a/test_fixtures/masp_proofs/473EDF0B2908F047110AC52C7F7ECD8CFD237A237C63AA565FC44893414EE7FC.bin and b/test_fixtures/masp_proofs/473EDF0B2908F047110AC52C7F7ECD8CFD237A237C63AA565FC44893414EE7FC.bin differ diff --git a/test_fixtures/masp_proofs/4B412E2EA5AC98758E696AB36327E2CFFC5F8055CE2E2FAFB4DE8E7C2216D5F8.bin b/test_fixtures/masp_proofs/4B412E2EA5AC98758E696AB36327E2CFFC5F8055CE2E2FAFB4DE8E7C2216D5F8.bin index 0d8eba575d..74e9d12700 100644 Binary files a/test_fixtures/masp_proofs/4B412E2EA5AC98758E696AB36327E2CFFC5F8055CE2E2FAFB4DE8E7C2216D5F8.bin and b/test_fixtures/masp_proofs/4B412E2EA5AC98758E696AB36327E2CFFC5F8055CE2E2FAFB4DE8E7C2216D5F8.bin differ diff --git a/test_fixtures/masp_proofs/4CCB9ADD3188CD893508CBB4FCB62D08DAA52F4DE496209BDAEFD36E75EAE98D.bin b/test_fixtures/masp_proofs/4CCB9ADD3188CD893508CBB4FCB62D08DAA52F4DE496209BDAEFD36E75EAE98D.bin index d706d3082d..81abdc75f1 100644 Binary files a/test_fixtures/masp_proofs/4CCB9ADD3188CD893508CBB4FCB62D08DAA52F4DE496209BDAEFD36E75EAE98D.bin and b/test_fixtures/masp_proofs/4CCB9ADD3188CD893508CBB4FCB62D08DAA52F4DE496209BDAEFD36E75EAE98D.bin differ diff --git a/test_fixtures/masp_proofs/553C507BF748CC2353DCE98EB91B5464810F6974083CC2FEE2756ED1E97B8143.bin b/test_fixtures/masp_proofs/553C507BF748CC2353DCE98EB91B5464810F6974083CC2FEE2756ED1E97B8143.bin index 53d50161df..eae0ffd803 100644 Binary files a/test_fixtures/masp_proofs/553C507BF748CC2353DCE98EB91B5464810F6974083CC2FEE2756ED1E97B8143.bin and b/test_fixtures/masp_proofs/553C507BF748CC2353DCE98EB91B5464810F6974083CC2FEE2756ED1E97B8143.bin differ diff --git a/test_fixtures/masp_proofs/60C29BD5C1B461533ECD82F3A0A71E2A0FD100F99D737415E6D9125F5A7046D4.bin b/test_fixtures/masp_proofs/60C29BD5C1B461533ECD82F3A0A71E2A0FD100F99D737415E6D9125F5A7046D4.bin index d138bb920c..d372fe5266 100644 Binary files a/test_fixtures/masp_proofs/60C29BD5C1B461533ECD82F3A0A71E2A0FD100F99D737415E6D9125F5A7046D4.bin and b/test_fixtures/masp_proofs/60C29BD5C1B461533ECD82F3A0A71E2A0FD100F99D737415E6D9125F5A7046D4.bin differ diff --git a/test_fixtures/masp_proofs/8BA2DA741BF1FE1CDEC5295AE3ECBE1A9EAF3496A30D69069DE2FBD293EEC978.bin b/test_fixtures/masp_proofs/8BA2DA741BF1FE1CDEC5295AE3ECBE1A9EAF3496A30D69069DE2FBD293EEC978.bin index a9585f06a3..d769dbffb2 100644 Binary files a/test_fixtures/masp_proofs/8BA2DA741BF1FE1CDEC5295AE3ECBE1A9EAF3496A30D69069DE2FBD293EEC978.bin and b/test_fixtures/masp_proofs/8BA2DA741BF1FE1CDEC5295AE3ECBE1A9EAF3496A30D69069DE2FBD293EEC978.bin differ diff --git a/test_fixtures/masp_proofs/978C35E058808D61F0E265D72DE8DD6A8E6226394EA6E3DFE1CFC10F69C0ACE0.bin b/test_fixtures/masp_proofs/978C35E058808D61F0E265D72DE8DD6A8E6226394EA6E3DFE1CFC10F69C0ACE0.bin index bd266d7cb7..07dd723a1c 100644 Binary files a/test_fixtures/masp_proofs/978C35E058808D61F0E265D72DE8DD6A8E6226394EA6E3DFE1CFC10F69C0ACE0.bin and b/test_fixtures/masp_proofs/978C35E058808D61F0E265D72DE8DD6A8E6226394EA6E3DFE1CFC10F69C0ACE0.bin differ diff --git a/test_fixtures/masp_proofs/AE4CEC9192B52E8CE5AB0C25936D2AEEF55A6F202D8EB4564017DB5BEF872107.bin b/test_fixtures/masp_proofs/AE4CEC9192B52E8CE5AB0C25936D2AEEF55A6F202D8EB4564017DB5BEF872107.bin index c8597c5928..3abf9372de 100644 Binary files a/test_fixtures/masp_proofs/AE4CEC9192B52E8CE5AB0C25936D2AEEF55A6F202D8EB4564017DB5BEF872107.bin and b/test_fixtures/masp_proofs/AE4CEC9192B52E8CE5AB0C25936D2AEEF55A6F202D8EB4564017DB5BEF872107.bin differ diff --git a/test_fixtures/masp_proofs/BB9AA71A4227C9E62948CBA8DB4A5C2232840271F032F756953233DB3E53E757.bin b/test_fixtures/masp_proofs/BB9AA71A4227C9E62948CBA8DB4A5C2232840271F032F756953233DB3E53E757.bin index efc70454f3..822ad25f4e 100644 Binary files a/test_fixtures/masp_proofs/BB9AA71A4227C9E62948CBA8DB4A5C2232840271F032F756953233DB3E53E757.bin and b/test_fixtures/masp_proofs/BB9AA71A4227C9E62948CBA8DB4A5C2232840271F032F756953233DB3E53E757.bin differ diff --git a/test_fixtures/masp_proofs/C506FA6C2EFB37B06CD5A473AF5CC6F78791F8954A0219C07B15344AEE0D2E0F.bin b/test_fixtures/masp_proofs/C506FA6C2EFB37B06CD5A473AF5CC6F78791F8954A0219C07B15344AEE0D2E0F.bin index 93d4512e29..c8142bf719 100644 Binary files a/test_fixtures/masp_proofs/C506FA6C2EFB37B06CD5A473AF5CC6F78791F8954A0219C07B15344AEE0D2E0F.bin and b/test_fixtures/masp_proofs/C506FA6C2EFB37B06CD5A473AF5CC6F78791F8954A0219C07B15344AEE0D2E0F.bin differ diff --git a/test_fixtures/masp_proofs/D007D1734AD42D34174F04566899481AB5F7C8F57502C5EAB2BF7594EA6CED8F.bin b/test_fixtures/masp_proofs/D007D1734AD42D34174F04566899481AB5F7C8F57502C5EAB2BF7594EA6CED8F.bin index 5d25b190ee..c1908eb8c6 100644 Binary files a/test_fixtures/masp_proofs/D007D1734AD42D34174F04566899481AB5F7C8F57502C5EAB2BF7594EA6CED8F.bin and b/test_fixtures/masp_proofs/D007D1734AD42D34174F04566899481AB5F7C8F57502C5EAB2BF7594EA6CED8F.bin differ diff --git a/test_fixtures/masp_proofs/DEDF664AD06184041515677A72699E65D4B40A4E1BC9E7A32D63CF28466A2F20.bin b/test_fixtures/masp_proofs/DEDF664AD06184041515677A72699E65D4B40A4E1BC9E7A32D63CF28466A2F20.bin index 646e615e69..a1ca366c18 100644 Binary files a/test_fixtures/masp_proofs/DEDF664AD06184041515677A72699E65D4B40A4E1BC9E7A32D63CF28466A2F20.bin and b/test_fixtures/masp_proofs/DEDF664AD06184041515677A72699E65D4B40A4E1BC9E7A32D63CF28466A2F20.bin differ diff --git a/test_fixtures/masp_proofs/F0471ECBD3AF04B4A373D2966781D5DEF92B9A9BB3A159947560514682CC3877.bin b/test_fixtures/masp_proofs/F0471ECBD3AF04B4A373D2966781D5DEF92B9A9BB3A159947560514682CC3877.bin index f1838aff67..e935f74a52 100644 Binary files a/test_fixtures/masp_proofs/F0471ECBD3AF04B4A373D2966781D5DEF92B9A9BB3A159947560514682CC3877.bin and b/test_fixtures/masp_proofs/F0471ECBD3AF04B4A373D2966781D5DEF92B9A9BB3A159947560514682CC3877.bin differ diff --git a/tests/src/e2e/eth_bridge_tests.rs b/tests/src/e2e/eth_bridge_tests.rs index e31665eb77..86a2971d11 100644 --- a/tests/src/e2e/eth_bridge_tests.rs +++ b/tests/src/e2e/eth_bridge_tests.rs @@ -70,7 +70,7 @@ fn run_ledger_with_ethereum_events_endpoint() -> Result<()> { set_ethereum_bridge_mode( &test, &test.net.chain_id, - &Who::Validator(0), + Who::Validator(0), ethereum_bridge::ledger::Mode::SelfHostedEndpoint, Some(DEFAULT_ETHEREUM_EVENTS_LISTEN_ADDR), ); @@ -315,7 +315,7 @@ async fn test_bridge_pool_e2e() { set_ethereum_bridge_mode( &test, &test.net.chain_id, - &Who::Validator(0), + Who::Validator(0), ethereum_bridge::ledger::Mode::SelfHostedEndpoint, Some(DEFAULT_ETHEREUM_EVENTS_LISTEN_ADDR), ); @@ -530,7 +530,7 @@ async fn test_wnam_transfer() -> Result<()> { set_ethereum_bridge_mode( &test, &test.net.chain_id, - &Who::Validator(0), + Who::Validator(0), ethereum_bridge::ledger::Mode::SelfHostedEndpoint, Some(DEFAULT_ETHEREUM_EVENTS_LISTEN_ADDR), ); @@ -565,7 +565,7 @@ async fn test_wnam_transfer() -> Result<()> { // check NAM balance of receiver and bridge let receiver_balance = find_balance( &test, - &Who::Validator(0), + Who::Validator(0), &native_token_address, &wnam_transfer.receiver, )?; @@ -573,7 +573,7 @@ async fn test_wnam_transfer() -> Result<()> { let bridge_balance = find_balance( &test, - &Who::Validator(0), + Who::Validator(0), &native_token_address, &BRIDGE_ADDRESS, )?; @@ -626,7 +626,7 @@ fn test_configure_oracle_from_storage() -> Result<()> { set_ethereum_bridge_mode( &test, &test.net.chain_id, - &Who::Validator(0), + Who::Validator(0), ethereum_bridge::ledger::Mode::RemoteEndpoint, None, ); @@ -673,7 +673,7 @@ async fn test_dai_transfer_implicit() -> Result<()> { let albert_wdai_balance = find_wrapped_erc20_balance( &test, - &Who::Validator(0), + Who::Validator(0), &DAI_ERC20_ETH_ADDRESS, &albert_addr, )?; @@ -689,7 +689,7 @@ async fn test_dai_transfer_established() -> Result<()> { // create an established account that Albert controls let established_alias = "albert-established"; - let rpc_address = get_actor_rpc(&test, &Who::Validator(0)); + let rpc_address = get_actor_rpc(&test, Who::Validator(0)); init_established_account( &test, &rpc_address, @@ -712,7 +712,7 @@ async fn test_dai_transfer_established() -> Result<()> { let established_wdai_balance = find_wrapped_erc20_balance( &test, - &Who::Validator(0), + Who::Validator(0), &DAI_ERC20_ETH_ADDRESS, &established_addr, )?; @@ -742,7 +742,7 @@ async fn test_wdai_transfer_implicit_unauthorized() -> Result<()> { let albert_wdai_balance = find_wrapped_erc20_balance( &test, - &Who::Validator(0), + Who::Validator(0), &DAI_ERC20_ETH_ADDRESS, &albert_addr, )?; @@ -754,7 +754,7 @@ async fn test_wdai_transfer_implicit_unauthorized() -> Result<()> { // signed with Albert's key let mut cmd = attempt_wrapped_erc20_transfer( &test, - &Who::Validator(0), + Who::Validator(0), &DAI_ERC20_ETH_ADDRESS, &albert_addr.to_string(), &bertha_addr.to_string(), @@ -768,7 +768,7 @@ async fn test_wdai_transfer_implicit_unauthorized() -> Result<()> { // check balances are unchanged after an unsuccessful transfer let albert_wdai_balance = find_wrapped_erc20_balance( &test, - &Who::Validator(0), + Who::Validator(0), &DAI_ERC20_ETH_ADDRESS, &albert_addr, )?; @@ -787,7 +787,7 @@ async fn test_wdai_transfer_established_unauthorized() -> Result<()> { let initial_transfer_amount = token::Amount::from(10_000_000); // create an established account that Albert controls let albert_established_alias = "albert-established"; - let rpc_address = get_actor_rpc(&test, &Who::Validator(0)); + let rpc_address = get_actor_rpc(&test, Who::Validator(0)); init_established_account( &test, &rpc_address, @@ -809,7 +809,7 @@ async fn test_wdai_transfer_established_unauthorized() -> Result<()> { let albert_wdai_balance = find_wrapped_erc20_balance( &test, - &Who::Validator(0), + Who::Validator(0), &DAI_ERC20_ETH_ADDRESS, &albert_established_addr, )?; @@ -821,7 +821,7 @@ async fn test_wdai_transfer_established_unauthorized() -> Result<()> { // signed with Albert's key let mut cmd = attempt_wrapped_erc20_transfer( &test, - &Who::Validator(0), + Who::Validator(0), &DAI_ERC20_ETH_ADDRESS, &albert_established_addr.to_string(), &bertha_addr.to_string(), @@ -835,7 +835,7 @@ async fn test_wdai_transfer_established_unauthorized() -> Result<()> { // check balances are unchanged after an unsuccessful transfer let albert_wdai_balance = find_wrapped_erc20_balance( &test, - &Who::Validator(0), + Who::Validator(0), &DAI_ERC20_ETH_ADDRESS, &albert_established_addr, )?; @@ -864,7 +864,7 @@ async fn test_wdai_transfer_implicit_to_implicit() -> Result<()> { let albert_wdai_balance = find_wrapped_erc20_balance( &test, - &Who::Validator(0), + Who::Validator(0), &DAI_ERC20_ETH_ADDRESS, &albert_addr, )?; @@ -877,7 +877,7 @@ async fn test_wdai_transfer_implicit_to_implicit() -> Result<()> { &token::DenominatedAmount::new(token::Amount::from(10_000), 0u8.into()); let mut cmd = attempt_wrapped_erc20_transfer( &test, - &Who::Validator(0), + Who::Validator(0), &DAI_ERC20_ETH_ADDRESS, &albert_addr.to_string(), &bertha_addr.to_string(), @@ -890,7 +890,7 @@ async fn test_wdai_transfer_implicit_to_implicit() -> Result<()> { let albert_wdai_balance = find_wrapped_erc20_balance( &test, - &Who::Validator(0), + Who::Validator(0), &DAI_ERC20_ETH_ADDRESS, &albert_addr, )?; @@ -901,7 +901,7 @@ async fn test_wdai_transfer_implicit_to_implicit() -> Result<()> { let bertha_wdai_balance = find_wrapped_erc20_balance( &test, - &Who::Validator(0), + Who::Validator(0), &DAI_ERC20_ETH_ADDRESS, &bertha_addr, )?; @@ -928,7 +928,7 @@ async fn test_wdai_transfer_implicit_to_established() -> Result<()> { let albert_wdai_balance = find_wrapped_erc20_balance( &test, - &Who::Validator(0), + Who::Validator(0), &DAI_ERC20_ETH_ADDRESS, &albert_addr, )?; @@ -936,7 +936,7 @@ async fn test_wdai_transfer_implicit_to_established() -> Result<()> { // create an established account that Bertha controls let bertha_established_alias = "bertha-established"; - let rpc_address = get_actor_rpc(&test, &Who::Validator(0)); + let rpc_address = get_actor_rpc(&test, Who::Validator(0)); init_established_account( &test, &rpc_address, @@ -953,7 +953,7 @@ async fn test_wdai_transfer_implicit_to_established() -> Result<()> { &token::DenominatedAmount::new(token::Amount::from(10_000), 0u8.into()); let mut cmd = attempt_wrapped_erc20_transfer( &test, - &Who::Validator(0), + Who::Validator(0), &DAI_ERC20_ETH_ADDRESS, &albert_addr.to_string(), &bertha_established_addr.to_string(), @@ -966,7 +966,7 @@ async fn test_wdai_transfer_implicit_to_established() -> Result<()> { let albert_wdai_balance = find_wrapped_erc20_balance( &test, - &Who::Validator(0), + Who::Validator(0), &DAI_ERC20_ETH_ADDRESS, &albert_addr, )?; @@ -977,7 +977,7 @@ async fn test_wdai_transfer_implicit_to_established() -> Result<()> { let bertha_established_wdai_balance = find_wrapped_erc20_balance( &test, - &Who::Validator(0), + Who::Validator(0), &DAI_ERC20_ETH_ADDRESS, &bertha_established_addr, )?; @@ -995,7 +995,7 @@ async fn test_wdai_transfer_established_to_implicit() -> Result<()> { // create an established account that Albert controls let albert_established_alias = "albert-established"; - let rpc_address = get_actor_rpc(&test, &Who::Validator(0)); + let rpc_address = get_actor_rpc(&test, Who::Validator(0)); init_established_account( &test, &rpc_address, @@ -1018,7 +1018,7 @@ async fn test_wdai_transfer_established_to_implicit() -> Result<()> { let albert_established_wdai_balance = find_wrapped_erc20_balance( &test, - &Who::Validator(0), + Who::Validator(0), &DAI_ERC20_ETH_ADDRESS, &albert_established_addr, )?; @@ -1032,7 +1032,7 @@ async fn test_wdai_transfer_established_to_implicit() -> Result<()> { &token::DenominatedAmount::new(token::Amount::from(10_000), 0u8.into()); let mut cmd = attempt_wrapped_erc20_transfer( &test, - &Who::Validator(0), + Who::Validator(0), &DAI_ERC20_ETH_ADDRESS, &albert_established_addr.to_string(), &bertha_addr.to_string(), @@ -1045,7 +1045,7 @@ async fn test_wdai_transfer_established_to_implicit() -> Result<()> { let albert_established_wdai_balance = find_wrapped_erc20_balance( &test, - &Who::Validator(0), + Who::Validator(0), &DAI_ERC20_ETH_ADDRESS, &albert_established_addr, )?; @@ -1056,7 +1056,7 @@ async fn test_wdai_transfer_established_to_implicit() -> Result<()> { let bertha_wdai_balance = find_wrapped_erc20_balance( &test, - &Who::Validator(0), + Who::Validator(0), &DAI_ERC20_ETH_ADDRESS, &bertha_addr, )?; @@ -1073,7 +1073,7 @@ async fn test_wdai_transfer_established_to_established() -> Result<()> { // create an established account that Albert controls let albert_established_alias = "albert-established"; - let rpc_address = get_actor_rpc(&test, &Who::Validator(0)); + let rpc_address = get_actor_rpc(&test, Who::Validator(0)); init_established_account( &test, &rpc_address, @@ -1096,7 +1096,7 @@ async fn test_wdai_transfer_established_to_established() -> Result<()> { let albert_established_wdai_balance = find_wrapped_erc20_balance( &test, - &Who::Validator(0), + Who::Validator(0), &DAI_ERC20_ETH_ADDRESS, &albert_established_addr, )?; @@ -1120,7 +1120,7 @@ async fn test_wdai_transfer_established_to_established() -> Result<()> { &token::DenominatedAmount::new(token::Amount::from(10_000), 0u8.into()); let mut cmd = attempt_wrapped_erc20_transfer( &test, - &Who::Validator(0), + Who::Validator(0), &DAI_ERC20_ETH_ADDRESS, &albert_established_addr.to_string(), &bertha_established_addr.to_string(), @@ -1133,7 +1133,7 @@ async fn test_wdai_transfer_established_to_established() -> Result<()> { let albert_established_wdai_balance = find_wrapped_erc20_balance( &test, - &Who::Validator(0), + Who::Validator(0), &DAI_ERC20_ETH_ADDRESS, &albert_established_addr, )?; @@ -1144,7 +1144,7 @@ async fn test_wdai_transfer_established_to_established() -> Result<()> { let bertha_established_wdai_balance = find_wrapped_erc20_balance( &test, - &Who::Validator(0), + Who::Validator(0), &DAI_ERC20_ETH_ADDRESS, &bertha_established_addr, )?; diff --git a/tests/src/e2e/eth_bridge_tests/helpers.rs b/tests/src/e2e/eth_bridge_tests/helpers.rs index 9fbc467443..3c7241cdce 100644 --- a/tests/src/e2e/eth_bridge_tests/helpers.rs +++ b/tests/src/e2e/eth_bridge_tests/helpers.rs @@ -114,7 +114,7 @@ pub fn setup_single_validator_test() -> Result<(Test, NamadaBgCmd)> { set_ethereum_bridge_mode( &test, &test.net.chain_id, - &Who::Validator(0), + Who::Validator(0), ethereum_bridge::ledger::Mode::SelfHostedEndpoint, Some(DEFAULT_ETHEREUM_EVENTS_LISTEN_ADDR), ); @@ -163,7 +163,7 @@ pub async fn send_transfer_to_namada_event( /// This will fail if the keys for `signer` are not in the local wallet. pub fn attempt_wrapped_erc20_transfer( test: &Test, - node: &Who, + node: Who, asset: &EthAddress, from: &str, to: &str, @@ -198,7 +198,7 @@ pub fn attempt_wrapped_erc20_transfer( /// been involved in a wrapped ERC20 transfer of any kind). pub fn find_wrapped_erc20_balance( test: &Test, - node: &Who, + node: Who, asset: &EthAddress, owner: &Address, ) -> Result { diff --git a/tests/src/e2e/helpers.rs b/tests/src/e2e/helpers.rs index 9fe5194da6..81488cba94 100644 --- a/tests/src/e2e/helpers.rs +++ b/tests/src/e2e/helpers.rs @@ -130,7 +130,7 @@ pub fn find_address(test: &Test, alias: impl AsRef) -> Result
{ #[allow(dead_code)] pub fn find_balance( test: &Test, - node: &Who, + node: Who, token: &Address, owner: &Address, ) -> Result { @@ -162,7 +162,7 @@ pub fn find_balance( } /// Find the address of the node's RPC endpoint. -pub fn get_actor_rpc(test: &Test, who: &Who) -> String { +pub fn get_actor_rpc(test: &Test, who: Who) -> String { let base_dir = test.get_base_dir(who); let tendermint_mode = match who { Who::NonValidator => TendermintMode::Full, @@ -176,7 +176,7 @@ pub fn get_actor_rpc(test: &Test, who: &Who) -> String { } /// Get some nodes's wallet. -pub fn get_node_wallet(test: &Test, who: &Who) -> Wallet { +pub fn get_node_wallet(test: &Test, who: Who) -> Wallet { let wallet_store_dir = test.get_base_dir(who).join(test.net.chain_id.as_str()); let mut wallet = FsWalletUtils::new(wallet_store_dir); @@ -185,7 +185,7 @@ pub fn get_node_wallet(test: &Test, who: &Who) -> Wallet { } /// Get the public key of the validator -pub fn get_validator_pk(test: &Test, who: &Who) -> Option { +pub fn get_validator_pk(test: &Test, who: Who) -> Option { let index = match who { Who::NonValidator => return None, Who::Validator(i) => i, @@ -381,7 +381,9 @@ pub fn wait_for_block_height( break Ok(()); } if Instant::now().duration_since(start) > loop_timeout { - panic!("Timed out waiting for height {height}, current {current}"); + return Err(eyre!( + "Timed out waiting for height {height}, current {current}" + )); } sleep(1); } diff --git a/tests/src/e2e/ibc_tests.rs b/tests/src/e2e/ibc_tests.rs index 1ea7667f57..a73bc30808 100644 --- a/tests/src/e2e/ibc_tests.rs +++ b/tests/src/e2e/ibc_tests.rs @@ -96,14 +96,14 @@ fn run_ledger_ibc() -> Result<()> { set_ethereum_bridge_mode( &test_a, &test_a.net.chain_id, - &Who::Validator(0), + Who::Validator(0), ethereum_bridge::ledger::Mode::Off, None, ); set_ethereum_bridge_mode( &test_b, &test_b.net.chain_id, - &Who::Validator(0), + Who::Validator(0), ethereum_bridge::ledger::Mode::Off, None, ); @@ -265,7 +265,7 @@ fn setup_two_single_node_nets() -> Result<(Test, Test)> { .map_err(|_| eyre!("Could not read genesis files from test b"))?; // chain b's validator needs to listen on a different port than chain a's // validator - let validator_pk = get_validator_pk(&test_b, &Who::Validator(0)).unwrap(); + let validator_pk = get_validator_pk(&test_b, Who::Validator(0)).unwrap(); let validator_addr = genesis_b .transactions .established_account @@ -349,7 +349,7 @@ fn create_client(test_a: &Test, test_b: &Test) -> Result<(ClientId, ClientId)> { } fn make_client_state(test: &Test, height: Height) -> TmClientState { - let rpc = get_actor_rpc(test, &Who::Validator(0)); + let rpc = get_actor_rpc(test, Who::Validator(0)); let ledger_address = TendermintAddress::from_str(&rpc).unwrap(); let client = HttpClient::new(ledger_address).unwrap(); @@ -473,12 +473,12 @@ fn update_client( } fn make_light_client_io(test: &Test) -> TmLightClientIo { - let addr = format!("http://{}", get_actor_rpc(test, &Who::Validator(0))); + let addr = format!("http://{}", get_actor_rpc(test, Who::Validator(0))); let rpc_addr = Url::from_str(&addr).unwrap(); let rpc_client = HttpClient::new(rpc_addr).unwrap(); let rpc_timeout = Duration::new(10, 0); - let pk = get_validator_pk(test, &Who::Validator(0)).unwrap(); + let pk = get_validator_pk(test, Who::Validator(0)).unwrap(); let peer_id = id_from_pk(&PublicKey::try_from_pk(&pk).unwrap()); TmLightClientIo::new(peer_id, rpc_client, Some(rpc_timeout)) @@ -867,7 +867,7 @@ fn transfer_received_token( channel_id: &ChannelId, test: &Test, ) -> Result<()> { - let rpc = get_actor_rpc(test, &Who::Validator(0)); + let rpc = get_actor_rpc(test, Who::Validator(0)); let ibc_denom = format!("{port_id}/{channel_id}/nam"); let amount = Amount::native_whole(50000).to_string_native(); let tx_args = [ @@ -1022,7 +1022,7 @@ fn shielded_transfer( ) -> Result<()> { // Get masp proof for the following IBC transfer from the destination chain // It will send 10 BTC from Chain A to PA(B) on Chain B - let rpc_b = get_actor_rpc(test_b, &Who::Validator(0)); + let rpc_b = get_actor_rpc(test_b, Who::Validator(0)); let output_folder = test_b.test_dir.path().to_string_lossy(); let amount = Amount::native_whole(10).to_string_native(); let args = [ @@ -1178,7 +1178,7 @@ fn submit_ibc_tx( std::fs::write(&data_path, data).expect("writing data failed"); let data_path = data_path.to_string_lossy(); - let rpc = get_actor_rpc(test, &Who::Validator(0)); + let rpc = get_actor_rpc(test, Who::Validator(0)); let mut client = run!( test, Bin::Client, @@ -1221,7 +1221,7 @@ fn transfer( expected_err: Option<&str>, wait_reveal_pk: bool, ) -> Result { - let rpc = get_actor_rpc(test, &Who::Validator(0)); + let rpc = get_actor_rpc(test, Who::Validator(0)); let channel_id = channel_id.to_string(); let port_id = port_id.to_string(); @@ -1311,7 +1311,7 @@ fn make_ibc_data(message: impl Msg) -> Vec { } fn query_height(test: &Test) -> Result { - let rpc = get_actor_rpc(test, &Who::Validator(0)); + let rpc = get_actor_rpc(test, Who::Validator(0)); let ledger_address = TendermintAddress::from_str(&rpc).unwrap(); let client = HttpClient::new(ledger_address).unwrap(); @@ -1324,7 +1324,7 @@ fn query_height(test: &Test) -> Result { } fn query_header(test: &Test, height: Height) -> Result { - let rpc = get_actor_rpc(test, &Who::Validator(0)); + let rpc = get_actor_rpc(test, Who::Validator(0)); let ledger_address = TendermintAddress::from_str(&rpc).unwrap(); let client = HttpClient::new(ledger_address).unwrap(); let height = height.revision_height() as u32; @@ -1345,7 +1345,7 @@ fn check_ibc_update_query( client_id: &ClientId, consensus_height: BlockHeight, ) -> Result<()> { - let rpc = get_actor_rpc(test, &Who::Validator(0)); + let rpc = get_actor_rpc(test, Who::Validator(0)); let ledger_address = TendermintAddress::from_str(&rpc).unwrap(); let client = HttpClient::new(ledger_address).unwrap(); match test.async_runtime().block_on(RPC.shell().ibc_client_update( @@ -1364,7 +1364,7 @@ fn check_ibc_packet_query( event_type: &EventType, packet: &Packet, ) -> Result<()> { - let rpc = get_actor_rpc(test, &Who::Validator(0)); + let rpc = get_actor_rpc(test, Who::Validator(0)); let ledger_address = TendermintAddress::from_str(&rpc).unwrap(); let client = HttpClient::new(ledger_address).unwrap(); match test.async_runtime().block_on(RPC.shell().ibc_packet( @@ -1387,7 +1387,7 @@ fn query_value_with_proof( key: &Key, height: Option, ) -> Result<(Option>, TmProof)> { - let rpc = get_actor_rpc(test, &Who::Validator(0)); + let rpc = get_actor_rpc(test, Who::Validator(0)); let ledger_address = TendermintAddress::from_str(&rpc).unwrap(); let client = HttpClient::new(ledger_address).unwrap(); let result = test.async_runtime().block_on(query_storage_value_bytes( @@ -1425,7 +1425,7 @@ fn check_balances( test_b: &Test, ) -> Result<()> { // Check the balances on Chain A - let rpc_a = get_actor_rpc(test_a, &Who::Validator(0)); + let rpc_a = get_actor_rpc(test_a, Who::Validator(0)); // Check the escrowed balance let escrow = Address::Internal(InternalAddress::Ibc).to_string(); let query_args = vec![ @@ -1444,7 +1444,7 @@ fn check_balances( // Check the balance on Chain B let trace_path = format!("{}/{}", &dest_port_id, &dest_channel_id); - let rpc_b = get_actor_rpc(test_b, &Who::Validator(0)); + let rpc_b = get_actor_rpc(test_b, Who::Validator(0)); let query_args = vec![ "balance", "--owner", BERTHA, "--token", NAM, "--node", &rpc_b, ]; @@ -1465,7 +1465,7 @@ fn check_balances_after_non_ibc( let trace_path = format!("{}/{}", port_id, channel_id); // Check the source - let rpc = get_actor_rpc(test, &Who::Validator(0)); + let rpc = get_actor_rpc(test, Who::Validator(0)); let query_args = vec!["balance", "--owner", BERTHA, "--token", NAM, "--node", &rpc]; let expected = format!("{}/nam: 50000", trace_path); @@ -1492,7 +1492,7 @@ fn check_balances_after_back( test_b: &Test, ) -> Result<()> { // Check the balances on Chain A - let rpc_a = get_actor_rpc(test_a, &Who::Validator(0)); + let rpc_a = get_actor_rpc(test_a, Who::Validator(0)); // Check the escrowed balance let escrow = Address::Internal(InternalAddress::Ibc).to_string(); let query_args = vec![ @@ -1511,7 +1511,7 @@ fn check_balances_after_back( // Check the balance on Chain B let trace_path = format!("{}/{}", dest_port_id, dest_channel_id); - let rpc_b = get_actor_rpc(test_b, &Who::Validator(0)); + let rpc_b = get_actor_rpc(test_b, Who::Validator(0)); let query_args = vec![ "balance", "--owner", BERTHA, "--token", NAM, "--node", &rpc_b, ]; @@ -1529,7 +1529,7 @@ fn check_shielded_balances( test_b: &Test, ) -> Result<()> { // Check the balance on Chain B - let rpc_b = get_actor_rpc(test_b, &Who::Validator(0)); + let rpc_b = get_actor_rpc(test_b, Who::Validator(0)); let query_args = vec![ "balance", "--owner", @@ -1640,7 +1640,7 @@ fn get_attributes_from_event(event: &AbciEvent) -> HashMap { } fn get_events(test: &Test, height: u32) -> Result> { - let rpc = get_actor_rpc(test, &Who::Validator(0)); + let rpc = get_actor_rpc(test, Who::Validator(0)); let ledger_address = TendermintAddress::from_str(&rpc).unwrap(); let client = HttpClient::new(ledger_address).unwrap(); diff --git a/tests/src/e2e/ledger_tests.rs b/tests/src/e2e/ledger_tests.rs index 28d140e6ad..c1f5c9d7a2 100644 --- a/tests/src/e2e/ledger_tests.rs +++ b/tests/src/e2e/ledger_tests.rs @@ -18,6 +18,7 @@ use std::time::{Duration, Instant}; use borsh_ext::BorshSerializeExt; use color_eyre::eyre::Result; +use color_eyre::owo_colors::OwoColorize; use data_encoding::HEXLOWER; use namada::types::address::Address; use namada::types::storage::Epoch; @@ -61,8 +62,7 @@ fn start_namada_ledger_node( Some(idx) => Who::Validator(idx), _ => Who::NonValidator, }; - let mut node = - run_as!(test, who.clone(), Bin::Node, &["ledger"], timeout_sec)?; + let mut node = run_as!(test, who, Bin::Node, &["ledger"], timeout_sec)?; node.exp_string("Namada ledger node started")?; if let Who::Validator(_) = who { node.exp_string("This node is a validator")?; @@ -92,7 +92,7 @@ fn run_ledger() -> Result<()> { set_ethereum_bridge_mode( &test, &test.net.chain_id, - &Who::Validator(0), + Who::Validator(0), ethereum_bridge::ledger::Mode::Off, None, ); @@ -133,20 +133,20 @@ fn test_node_connectivity_and_consensus() -> Result<()> { None, )?; - allow_duplicate_ips(&test, &test.net.chain_id, &Who::Validator(0)); - allow_duplicate_ips(&test, &test.net.chain_id, &Who::Validator(1)); + allow_duplicate_ips(&test, &test.net.chain_id, Who::Validator(0)); + allow_duplicate_ips(&test, &test.net.chain_id, Who::Validator(1)); set_ethereum_bridge_mode( &test, &test.net.chain_id, - &Who::Validator(0), + Who::Validator(0), ethereum_bridge::ledger::Mode::Off, None, ); set_ethereum_bridge_mode( &test, &test.net.chain_id, - &Who::Validator(1), + Who::Validator(1), ethereum_bridge::ledger::Mode::Off, None, ); @@ -162,7 +162,7 @@ fn test_node_connectivity_and_consensus() -> Result<()> { start_namada_ledger_node_wait_wasm(&test, None, Some(40))?.background(); // 2. Cross over epoch to check for consensus with multiple nodes - let validator_one_rpc = get_actor_rpc(&test, &Who::Validator(0)); + let validator_one_rpc = get_actor_rpc(&test, Who::Validator(0)); let _ = epoch_sleep(&test, &validator_one_rpc, 720)?; // 3. Submit a valid token transfer tx @@ -199,9 +199,9 @@ fn test_node_connectivity_and_consensus() -> Result<()> { let _bg_validator_0 = validator_0.background(); let _bg_validator_1 = validator_1.background(); - let validator_0_rpc = get_actor_rpc(&test, &Who::Validator(0)); - let validator_1_rpc = get_actor_rpc(&test, &Who::Validator(1)); - let non_validator_rpc = get_actor_rpc(&test, &Who::NonValidator); + let validator_0_rpc = get_actor_rpc(&test, Who::Validator(0)); + let validator_1_rpc = get_actor_rpc(&test, Who::Validator(1)); + let non_validator_rpc = get_actor_rpc(&test, Who::NonValidator); // Find the block height on the validator let after_tx_height = get_height(&test, &validator_0_rpc)?; @@ -236,7 +236,7 @@ fn test_namada_shuts_down_if_tendermint_dies() -> Result<()> { set_ethereum_bridge_mode( &test, &test.net.chain_id, - &Who::Validator(0), + Who::Validator(0), ethereum_bridge::ledger::Mode::Off, None, ); @@ -278,7 +278,7 @@ fn run_ledger_load_state_and_reset() -> Result<()> { set_ethereum_bridge_mode( &test, &test.net.chain_id, - &Who::Validator(0), + Who::Validator(0), ethereum_bridge::ledger::Mode::Off, None, ); @@ -292,7 +292,7 @@ fn run_ledger_load_state_and_reset() -> Result<()> { ledger.exp_regex(r"Committed block hash.*, height: [0-9]+")?; let bg_ledger = ledger.background(); // Wait for a new epoch - let validator_one_rpc = get_actor_rpc(&test, &Who::Validator(0)); + let validator_one_rpc = get_actor_rpc(&test, Who::Validator(0)); epoch_sleep(&test, &validator_one_rpc, 30)?; // 2. Shut it down @@ -361,7 +361,7 @@ fn suspend_ledger() -> Result<()> { let bg_ledger = ledger.background(); // 2. Query the ledger - let validator_one_rpc = get_actor_rpc(&test, &Who::Validator(0)); + let validator_one_rpc = get_actor_rpc(&test, Who::Validator(0)); let mut client = run!( test, Bin::Client, @@ -420,7 +420,7 @@ fn ledger_txs_and_queries() -> Result<()> { set_ethereum_bridge_mode( &test, &test.net.chain_id, - &Who::Validator(0), + Who::Validator(0), ethereum_bridge::ledger::Mode::Off, None, ); @@ -447,7 +447,7 @@ fn ledger_txs_and_queries() -> Result<()> { std::fs::write(&tx_data_path, transfer).unwrap(); let tx_data_path = tx_data_path.to_string_lossy(); - let validator_one_rpc = get_actor_rpc(&test, &Who::Validator(0)); + let validator_one_rpc = get_actor_rpc(&test, Who::Validator(0)); let multisig_account = format!("{},{},{}", BERTHA_KEY, ALBERT_KEY, CHRISTEL_KEY); @@ -710,7 +710,7 @@ fn wrapper_disposable_signer() -> Result<()> { start_namada_ledger_node_wait_wasm(&test, Some(0), Some(40))? .background(); - let validator_one_rpc = get_actor_rpc(&test, &Who::Validator(0)); + let validator_one_rpc = get_actor_rpc(&test, Who::Validator(0)); let _ep1 = epoch_sleep(&test, &validator_one_rpc, 720)?; @@ -794,7 +794,7 @@ fn invalid_transactions() -> Result<()> { set_ethereum_bridge_mode( &test, &test.net.chain_id, - &Who::Validator(0), + Who::Validator(0), ethereum_bridge::ledger::Mode::Off, None, ); @@ -806,7 +806,7 @@ fn invalid_transactions() -> Result<()> { // 2. Submit a an invalid transaction (trying to transfer tokens should fail // in the user's VP due to the wrong signer) - let validator_one_rpc = get_actor_rpc(&test, &Who::Validator(0)); + let validator_one_rpc = get_actor_rpc(&test, Who::Validator(0)); let tx_args = vec![ "transfer", @@ -935,12 +935,12 @@ fn pos_bonds() -> Result<()> { }, None, )?; - allow_duplicate_ips(&test, &test.net.chain_id, &Who::Validator(0)); - allow_duplicate_ips(&test, &test.net.chain_id, &Who::Validator(1)); + allow_duplicate_ips(&test, &test.net.chain_id, Who::Validator(0)); + allow_duplicate_ips(&test, &test.net.chain_id, Who::Validator(1)); set_ethereum_bridge_mode( &test, &test.net.chain_id, - &Who::Validator(0), + Who::Validator(0), ethereum_bridge::ledger::Mode::Off, None, ); @@ -950,7 +950,7 @@ fn pos_bonds() -> Result<()> { start_namada_ledger_node_wait_wasm(&test, Some(0), Some(40))? .background(); - let validator_0_rpc = get_actor_rpc(&test, &Who::Validator(0)); + let validator_0_rpc = get_actor_rpc(&test, Who::Validator(0)); // 2. Submit a self-bond for the first genesis validator let tx_args = vec![ @@ -1169,7 +1169,7 @@ fn pos_rewards() -> Result<()> { set_ethereum_bridge_mode( &test, &test.net.chain_id, - &Who::Validator(i), + Who::Validator(i), ethereum_bridge::ledger::Mode::Off, None, ); @@ -1180,7 +1180,7 @@ fn pos_rewards() -> Result<()> { start_namada_ledger_node_wait_wasm(&test, Some(0), Some(40))? .background(); - let validator_0_rpc = get_actor_rpc(&test, &Who::Validator(0)); + let validator_0_rpc = get_actor_rpc(&test, Who::Validator(0)); // Query the current rewards for the validator self-bond let tx_args = vec![ @@ -1343,7 +1343,7 @@ fn test_bond_queries() -> Result<()> { start_namada_ledger_node_wait_wasm(&test, Some(0), Some(40))? .background(); - let validator_one_rpc = get_actor_rpc(&test, &Who::Validator(0)); + let validator_one_rpc = get_actor_rpc(&test, Who::Validator(0)); let validator_alias = "validator-0"; // 2. Submit a delegation to the genesis validator @@ -1523,7 +1523,7 @@ fn pos_init_validator() -> Result<()> { non_validator.exp_string("Committed block hash")?; let bg_non_validator = non_validator.background(); - let non_validator_rpc = get_actor_rpc(&test, &Who::NonValidator); + let non_validator_rpc = get_actor_rpc(&test, Who::NonValidator); // 2. Initialize a new validator account with the non-validator node let new_validator = "new-validator"; @@ -1638,7 +1638,7 @@ fn pos_init_validator() -> Result<()> { } let loc = format!("{}:{}", std::file!(), std::line!()); - let validator_1_base_dir = test.get_base_dir(&Who::NonValidator); + let validator_1_base_dir = test.get_base_dir(Who::NonValidator); let mut validator_1 = setup::run_cmd( Bin::Node, ["ledger"], @@ -1702,7 +1702,7 @@ fn ledger_many_txs_in_a_block() -> Result<()> { set_ethereum_bridge_mode( &test, &test.net.chain_id, - &Who::Validator(0), + Who::Validator(0), ethereum_bridge::ledger::Mode::Off, None, ); @@ -1712,7 +1712,7 @@ fn ledger_many_txs_in_a_block() -> Result<()> { start_namada_ledger_node_wait_wasm(&test, Some(0), Some(40))? .background(); - let validator_one_rpc = Arc::new(get_actor_rpc(&test, &Who::Validator(0))); + let validator_one_rpc = Arc::new(get_actor_rpc(&test, Who::Validator(0))); // A token transfer tx args let tx_args = Arc::new(vec![ @@ -1788,7 +1788,7 @@ fn proposal_submission() -> Result<()> { set_ethereum_bridge_mode( &test, &test.net.chain_id, - &Who::Validator(0), + Who::Validator(0), ethereum_bridge::ledger::Mode::Off, None, ); @@ -1804,7 +1804,7 @@ fn proposal_submission() -> Result<()> { start_namada_ledger_node_wait_wasm(&test, Some(0), Some(40))? .background(); - let validator_0_rpc = get_actor_rpc(&test, &Who::Validator(0)); + let validator_0_rpc = get_actor_rpc(&test, Who::Validator(0)); // 1.1 Delegate some token let tx_args = vec![ @@ -1830,7 +1830,7 @@ fn proposal_submission() -> Result<()> { TestWasms::TxProposalCode.read_bytes(), 12, ); - let validator_one_rpc = get_actor_rpc(&test, &Who::Validator(0)); + let validator_one_rpc = get_actor_rpc(&test, Who::Validator(0)); let submit_proposal_args = vec![ "init-proposal", @@ -2113,7 +2113,7 @@ fn pgf_governance_proposal() -> Result<()> { set_ethereum_bridge_mode( &test, &test.net.chain_id, - &Who::Validator(0), + Who::Validator(0), ethereum_bridge::ledger::Mode::Off, None, ); @@ -2129,7 +2129,7 @@ fn pgf_governance_proposal() -> Result<()> { start_namada_ledger_node_wait_wasm(&test, Some(0), Some(40))? .background(); - let validator_one_rpc = get_actor_rpc(&test, &Who::Validator(0)); + let validator_one_rpc = get_actor_rpc(&test, Who::Validator(0)); // Delegate some token let tx_args = vec![ @@ -2157,7 +2157,7 @@ fn pgf_governance_proposal() -> Result<()> { let valid_proposal_json_path = prepare_proposal_data(&test, albert, pgf_stewards, 12); - let validator_one_rpc = get_actor_rpc(&test, &Who::Validator(0)); + let validator_one_rpc = get_actor_rpc(&test, Who::Validator(0)); let submit_proposal_args = vec![ "init-proposal", @@ -2349,7 +2349,7 @@ fn pgf_governance_proposal() -> Result<()> { let valid_proposal_json_path = prepare_proposal_data(&test, albert, pgf_funding, 36); - let validator_one_rpc = get_actor_rpc(&test, &Who::Validator(0)); + let validator_one_rpc = get_actor_rpc(&test, Who::Validator(0)); let submit_proposal_args = vec![ "init-proposal", @@ -2427,7 +2427,7 @@ fn proposal_offline() -> Result<()> { set_ethereum_bridge_mode( &test, &test.net.chain_id, - &Who::Validator(0), + Who::Validator(0), ethereum_bridge::ledger::Mode::Off, None, ); @@ -2437,7 +2437,7 @@ fn proposal_offline() -> Result<()> { start_namada_ledger_node_wait_wasm(&test, Some(0), Some(40))? .background(); - let validator_one_rpc = get_actor_rpc(&test, &Who::Validator(0)); + let validator_one_rpc = get_actor_rpc(&test, Who::Validator(0)); // 1.1 Delegate some token let tx_args = vec![ @@ -2488,7 +2488,7 @@ fn proposal_offline() -> Result<()> { epoch = get_epoch(&test, &validator_one_rpc).unwrap(); } - let validator_one_rpc = get_actor_rpc(&test, &Who::Validator(0)); + let validator_one_rpc = get_actor_rpc(&test, Who::Validator(0)); let offline_proposal_args = vec![ "init-proposal", @@ -2607,20 +2607,20 @@ fn double_signing_gets_slashed() -> Result<()> { None, )?; - allow_duplicate_ips(&test, &test.net.chain_id, &Who::Validator(0)); - allow_duplicate_ips(&test, &test.net.chain_id, &Who::Validator(1)); + allow_duplicate_ips(&test, &test.net.chain_id, Who::Validator(0)); + allow_duplicate_ips(&test, &test.net.chain_id, Who::Validator(1)); set_ethereum_bridge_mode( &test, &test.net.chain_id, - &Who::Validator(0), + Who::Validator(0), ethereum_bridge::ledger::Mode::Off, None, ); set_ethereum_bridge_mode( &test, &test.net.chain_id, - &Who::Validator(1), + Who::Validator(1), ethereum_bridge::ledger::Mode::Off, None, ); @@ -2647,7 +2647,7 @@ fn double_signing_gets_slashed() -> Result<()> { let _bg_validator_3 = validator_3.background(); // 2. Copy the first genesis validator base-dir - let validator_0_base_dir = test.get_base_dir(&Who::Validator(0)); + let validator_0_base_dir = test.get_base_dir(Who::Validator(0)); let validator_0_base_dir_copy = test .test_dir .path() @@ -2739,7 +2739,7 @@ fn double_signing_gets_slashed() -> Result<()> { let _bg_validator_0_copy = validator_0_copy.background(); // 5. Submit a valid token transfer tx to validator 0 - let validator_one_rpc = get_actor_rpc(&test, &Who::Validator(0)); + let validator_one_rpc = get_actor_rpc(&test, Who::Validator(0)); let tx_args = [ "transfer", "--source", @@ -2899,7 +2899,7 @@ fn implicit_account_reveal_pk() -> Result<()> { .background(); // 2. Some transactions that need signature authorization: - let validator_0_rpc = get_actor_rpc(&test, &Who::Validator(0)); + let validator_0_rpc = get_actor_rpc(&test, Who::Validator(0)); let txs_args: Vec Vec>> = vec![ // A token transfer tx Box::new(|source| { @@ -3038,7 +3038,7 @@ fn test_epoch_sleep() -> Result<()> { let _bg_ledger = ledger.background(); - let validator_one_rpc = get_actor_rpc(&test, &Who::Validator(0)); + let validator_one_rpc = get_actor_rpc(&test, Who::Validator(0)); // 2. Query the current epoch let start_epoch = get_epoch(&test, &validator_one_rpc).unwrap(); @@ -3128,12 +3128,12 @@ fn deactivate_and_reactivate_validator() -> Result<()> { }, None, )?; - allow_duplicate_ips(&test, &test.net.chain_id, &Who::Validator(0)); - allow_duplicate_ips(&test, &test.net.chain_id, &Who::Validator(1)); + allow_duplicate_ips(&test, &test.net.chain_id, Who::Validator(0)); + allow_duplicate_ips(&test, &test.net.chain_id, Who::Validator(1)); set_ethereum_bridge_mode( &test, &test.net.chain_id, - &Who::Validator(0), + Who::Validator(0), ethereum_bridge::ledger::Mode::Off, None, ); @@ -3147,7 +3147,7 @@ fn deactivate_and_reactivate_validator() -> Result<()> { start_namada_ledger_node_wait_wasm(&test, Some(1), Some(40))? .background(); - let validator_1_rpc = get_actor_rpc(&test, &Who::Validator(1)); + let validator_1_rpc = get_actor_rpc(&test, Who::Validator(1)); // Check the state of validator-1 let tx_args = vec![ @@ -3260,7 +3260,7 @@ fn change_validator_metadata() -> Result<()> { set_ethereum_bridge_mode( &test, &test.net.chain_id, - &Who::Validator(0), + Who::Validator(0), ethereum_bridge::ledger::Mode::Off, None, ); @@ -3270,7 +3270,7 @@ fn change_validator_metadata() -> Result<()> { start_namada_ledger_node_wait_wasm(&test, Some(0), Some(40))? .background(); - let validator_0_rpc = get_actor_rpc(&test, &Who::Validator(0)); + let validator_0_rpc = get_actor_rpc(&test, Who::Validator(0)); // 2. Query the validator metadata loaded from genesis let metadata_query_args = vec![ @@ -3398,7 +3398,7 @@ fn test_invalid_validator_txs() -> Result<()> { set_ethereum_bridge_mode( &test, &test.net.chain_id, - &Who::Validator(0), + Who::Validator(0), ethereum_bridge::ledger::Mode::Off, None, ); @@ -3412,8 +3412,8 @@ fn test_invalid_validator_txs() -> Result<()> { start_namada_ledger_node_wait_wasm(&test, Some(1), Some(40))? .background(); - let validator_0_rpc = get_actor_rpc(&test, &Who::Validator(0)); - let validator_1_rpc = get_actor_rpc(&test, &Who::Validator(1)); + let validator_0_rpc = get_actor_rpc(&test, Who::Validator(0)); + let validator_1_rpc = get_actor_rpc(&test, Who::Validator(1)); // Try to change validator-1 commission rate as validator-0 let tx_args = vec![ @@ -3529,3 +3529,129 @@ fn test_invalid_validator_txs() -> Result<()> { Ok(()) } + +/// Test change of consensus key of a validator from consensus set. +/// +/// 1. Run 2 genesis validator nodes. +/// 2. Change consensus key of validator-0 +/// 3. Check that no new blocks are being created - chain halted because +/// validator-0 consensus change took effect and it cannot sign with the old +/// key anymore +/// 4. Configure validator-0 node with the new key +/// 5. Resume the chain and check that blocks are being created +#[test] +fn change_consensus_key() -> Result<()> { + let min_num_of_blocks = 6; + let pipeline_len = 2; + let test = setup::network( + |mut genesis, base_dir| { + genesis.parameters.parameters.min_num_of_blocks = min_num_of_blocks; + genesis.parameters.parameters.max_expected_time_per_block = 1; + genesis.parameters.parameters.epochs_per_year = 31_536_000; + genesis.parameters.pos_params.pipeline_len = pipeline_len; + genesis.parameters.pos_params.unbonding_len = 4; + setup::set_validators(2, genesis, base_dir, default_port_offset) + }, + None, + )?; + + for i in 0..2 { + set_ethereum_bridge_mode( + &test, + &test.net.chain_id, + Who::Validator(i), + ethereum_bridge::ledger::Mode::Off, + None, + ); + } + + // ========================================================================= + // 1. Run 2 genesis validator ledger nodes + + let bg_validator_0 = + start_namada_ledger_node_wait_wasm(&test, Some(0), Some(40))? + .background(); + + let _bg_validator_1 = + start_namada_ledger_node_wait_wasm(&test, Some(1), Some(40))? + .background(); + + let validator_0_rpc = get_actor_rpc(&test, Who::Validator(0)); + + // ========================================================================= + // 2. Change consensus key of validator-0 + + let tx_args = vec![ + "change-consensus-key", + "--validator", + "validator-0", + "--signing-keys", + "validator-0-balance-key", + "--node", + &validator_0_rpc, + "--unsafe-dont-encrypt", + ]; + let mut client = + run_as!(test, Who::Validator(0), Bin::Client, tx_args, Some(40))?; + client.exp_string("Transaction is valid.")?; + client.assert_success(); + + // ========================================================================= + // 3. Check that no new blocks are being created - chain halted because + // validator-0 consensus change took effect and it cannot sign with the old + // key anymore + + // Wait for the next epoch + let validator_0_rpc = get_actor_rpc(&test, Who::Validator(0)); + let _epoch = epoch_sleep(&test, &validator_0_rpc, 30)?; + + // The chain should halt before the following (pipeline) epoch + let _err_report = epoch_sleep(&test, &validator_0_rpc, 30) + .expect_err("Chain should halt"); + + // Load validator-0 wallet + println!( + "{}", + "Setting up the new validator consensus key in CometBFT...".blue() + ); + let chain_dir = test.get_chain_dir(Who::Validator(0)); + let mut wallet = namada_apps::wallet::load(&chain_dir).unwrap(); + + // ========================================================================= + // 4. Configure validator-0 node with the new key + + // Get the new consensus SK + let new_key_alias = "validator-0-consensus-key-1"; + let new_sk = wallet.find_secret_key(new_key_alias, None).unwrap(); + // Write the key to CometBFT dir + let cometbft_dir = test.get_cometbft_home(Who::Validator(0)); + namada_apps::node::ledger::tendermint_node::write_validator_key( + cometbft_dir, + &new_sk, + ); + println!( + "{}", + "Done setting up the new validator consensus key in CometBFT.".blue() + ); + + // ========================================================================= + // 5. Resume the chain and check that blocks are being created + + // Restart validator-0 node + let mut validator_0 = bg_validator_0.foreground(); + validator_0.interrupt().unwrap(); + // Wait for the node to stop running + validator_0.exp_string("Namada ledger node has shut down.")?; + validator_0.exp_eof()?; + drop(validator_0); + + let mut validator_0 = start_namada_ledger_node(&test, Some(0), Some(40))?; + // Wait to commit a block + validator_0.exp_regex(r"Committed block hash.*, height: [0-9]+")?; + let _bg_validator_0 = validator_0.background(); + + // Continue to make blocks for another epoch + let _epoch = epoch_sleep(&test, &validator_0_rpc, 40)?; + + Ok(()) +} diff --git a/tests/src/e2e/setup.rs b/tests/src/e2e/setup.rs index b0415743d2..1db62a2fe1 100644 --- a/tests/src/e2e/setup.rs +++ b/tests/src/e2e/setup.rs @@ -86,7 +86,7 @@ pub fn default_port_offset(ix: u8) -> u16 { pub fn update_actor_config( test: &Test, chain_id: &ChainId, - who: &Who, + who: Who, update: F, ) where F: FnOnce(&mut Config), @@ -101,7 +101,7 @@ pub fn update_actor_config( } /// Configure validator p2p settings to allow duplicate ips -pub fn allow_duplicate_ips(test: &Test, chain_id: &ChainId, who: &Who) { +pub fn allow_duplicate_ips(test: &Test, chain_id: &ChainId, who: Who) { update_actor_config(test, chain_id, who, |config| { config.ledger.cometbft.p2p.allow_duplicate_ip = true; }); @@ -112,7 +112,7 @@ pub fn allow_duplicate_ips(test: &Test, chain_id: &ChainId, who: &Who) { pub fn set_ethereum_bridge_mode( test: &Test, chain_id: &ChainId, - who: &Who, + who: Who, mode: ethereum_bridge::ledger::Mode, rpc_endpoint: Option<&str>, ) { @@ -704,7 +704,7 @@ mod macros { } } -#[derive(Clone)] +#[derive(Clone, Copy, Debug)] pub enum Who { // A non-validator NonValidator, @@ -751,11 +751,11 @@ impl Test { I: IntoIterator, S: AsRef, { - let base_dir = self.get_base_dir(&who); + let base_dir = self.get_base_dir(who); run_cmd(bin, args, timeout_sec, &self.working_dir, base_dir, loc) } - pub fn get_base_dir(&self, who: &Who) -> PathBuf { + pub fn get_base_dir(&self, who: Who) -> PathBuf { match who { Who::NonValidator => self.test_dir.path().to_owned(), Who::Validator(index) => self @@ -766,6 +766,15 @@ impl Test { } } + pub fn get_chain_dir(&self, who: Who) -> PathBuf { + self.get_base_dir(who).join(self.net.chain_id.as_str()) + } + + pub fn get_cometbft_home(&self, who: Who) -> PathBuf { + self.get_chain_dir(who) + .join(namada_apps::config::COMETBFT_DIR) + } + /// Get an async runtime. pub fn async_runtime(&self) -> &tokio::runtime::Runtime { Lazy::force(&self.async_runtime.0) diff --git a/wasm/wasm_source/src/tx_change_consensus_key.rs b/wasm/wasm_source/src/tx_change_consensus_key.rs index 9f06745c9f..9d82f4d855 100644 --- a/wasm/wasm_source/src/tx_change_consensus_key.rs +++ b/wasm/wasm_source/src/tx_change_consensus_key.rs @@ -12,5 +12,15 @@ fn apply_tx(ctx: &mut Ctx, tx_data: Tx) -> TxResult { consensus_key, } = transaction::pos::ConsensusKeyChange::try_from_slice(&data[..]) .wrap_err("failed to decode Dec value")?; + + // Check that the tx has been signed with the new consensus key + if !matches!( + verify_signatures_of_pks(ctx, &signed, vec![consensus_key.clone()]), + Ok(true) + ) { + debug_log!("Consensus key ownership signature verification failed"); + panic!() + } + ctx.change_validator_consensus_key(&validator, &consensus_key) }