diff --git a/.github/workflows/integration.yaml b/.github/workflows/integration.yaml index dbdd309dfe..0b6b60bc41 100644 --- a/.github/workflows/integration.yaml +++ b/.github/workflows/integration.yaml @@ -45,7 +45,7 @@ jobs: fail-fast: false matrix: chain: - - package: gaia11 + - package: gaia12 command: gaiad account_prefix: cosmos - package: ibc-go-v4-simapp @@ -249,7 +249,7 @@ jobs: fail-fast: false matrix: chain: - - package: gaia11 + - package: gaia12 command: gaiad account_prefix: cosmos - package: juno @@ -295,7 +295,7 @@ jobs: fail-fast: false matrix: chain: - - package: .#gaia11 .#stride-no-admin + - package: .#gaia12 .#stride-no-admin command: gaiad,strided account_prefix: cosmos,stride steps: @@ -382,7 +382,7 @@ jobs: fail-fast: false matrix: chain: - - package: gaia11 + - package: gaia12 command: gaiad account_prefix: cosmos steps: @@ -458,7 +458,7 @@ jobs: CHAIN_COMMAND_PATHS: gaiad,${{ matrix.chain.command }} ACCOUNT_PREFIXES: cosmos,${{ matrix.chain.account_prefix }} run: | - nix shell .#gaia11 .#${{ matrix.chain.package }} -c \ + nix shell .#gaia12 .#${{ matrix.chain.package }} -c \ cargo nextest run -p ibc-integration-test --no-fail-fast --failure-output final --test-threads=2 \ --features interchain-security interchain_security:: @@ -501,7 +501,7 @@ jobs: CHAIN_COMMAND_PATHS: gaiad,${{ matrix.chain.command }} ACCOUNT_PREFIXES: cosmos,${{ matrix.chain.account_prefix }} run: | - nix shell .#gaia11 .#${{ matrix.chain.package }} -c \ + nix shell .#gaia12 .#${{ matrix.chain.package }} -c \ cargo nextest run -p ibc-integration-test --no-fail-fast --failure-output final --test-threads=2 \ --features interchain-security,ica interchain_security:: @@ -543,7 +543,7 @@ jobs: CHAIN_COMMAND_PATHS: gaiad,${{ matrix.chain.command }} ACCOUNT_PREFIXES: cosmos,${{ matrix.chain.account_prefix }} run: | - nix shell .#gaia11 .#${{ matrix.chain.package }} -c \ + nix shell .#gaia12 .#${{ matrix.chain.package }} -c \ cargo nextest run -p ibc-integration-test --no-fail-fast --failure-output final --test-threads=2 \ --features interchain-security,ics31 interchain_security:: diff --git a/.github/workflows/misbehaviour.yml b/.github/workflows/misbehaviour.yml index 26da00dc87..0e0d2f2f77 100644 --- a/.github/workflows/misbehaviour.yml +++ b/.github/workflows/misbehaviour.yml @@ -43,7 +43,7 @@ jobs: fail-fast: false matrix: chain: - - package: gaia11 + - package: gaia12 command: gaiad account_prefix: cosmos steps: diff --git a/.github/workflows/multi-chains.yaml b/.github/workflows/multi-chains.yaml index 590f004ede..8aab31647d 100644 --- a/.github/workflows/multi-chains.yaml +++ b/.github/workflows/multi-chains.yaml @@ -58,7 +58,7 @@ jobs: fail-fast: false matrix: first-package: - - package: gaia11 + - package: gaia12 command: gaiad account_prefix: cosmos - package: ibc-go-v7-simapp diff --git a/crates/relayer-cli/src/commands/tx/client.rs b/crates/relayer-cli/src/commands/tx/client.rs index 70edd167cf..8014baacee 100644 --- a/crates/relayer-cli/src/commands/tx/client.rs +++ b/crates/relayer-cli/src/commands/tx/client.rs @@ -434,8 +434,9 @@ impl Runnable for TxUpgradeClientsCmd { .chains .iter() .filter(|&chain| { - self.reference_chain_id != chain.id && self.host_chain_id.is_none() - || self.host_chain_id == Some(chain.id.clone()) + self.reference_chain_id != chain.id + && (self.host_chain_id.is_none() + || self.host_chain_id == Some(chain.id.clone())) }) .map(|chain| { self.upgrade_clients_for_chain( diff --git a/flake.lock b/flake.lock index 7b6daa44be..b165933c2b 100644 --- a/flake.lock +++ b/flake.lock @@ -813,11 +813,11 @@ }, "nixpkgs_3": { "locked": { - "lastModified": 1695609632, - "narHash": "sha256-+RWYu7xDgYI7KhzKv2Cdqb0mkPFsEr0FcV5mrUAu0SI=", + "lastModified": 1697009197, + "narHash": "sha256-viVRhBTFT8fPJTb1N3brQIpFZnttmwo3JVKNuWRVc3s=", "owner": "nixos", "repo": "nixpkgs", - "rev": "0a017f947fc9a060bfdd79a8e885f1d54fd8a592", + "rev": "01441e14af5e29c9d27ace398e6dd0b293e25a54", "type": "github" }, "original": { diff --git a/flake.nix b/flake.nix index 22e4896750..fafcb107e0 100644 --- a/flake.nix +++ b/flake.nix @@ -28,7 +28,7 @@ inherit (cosmos-nix) gaia6-ordered - gaia11 + gaia12 osmosis wasmd ibc-go-v2-simapp diff --git a/tools/test-framework/src/chain/cli/provider.rs b/tools/test-framework/src/chain/cli/provider.rs index b4c44dd672..e7f0a15522 100644 --- a/tools/test-framework/src/chain/cli/provider.rs +++ b/tools/test-framework/src/chain/cli/provider.rs @@ -1,6 +1,7 @@ +use std::collections::HashMap; use std::str; -use crate::chain::exec::simple_exec; +use crate::chain::exec::{simple_exec, ExecOutput}; use crate::error::Error; pub fn submit_consumer_chain_proposal( @@ -11,6 +12,7 @@ pub fn submit_consumer_chain_proposal( ) -> Result<(), Error> { let proposal_file = format!("{}/consumer_proposal.json", home_path); + // The submission might fail silently if there is not enough gas simple_exec( chain_id, command_path, @@ -30,6 +32,8 @@ pub fn submit_consumer_chain_proposal( rpc_listen_address, "--keyring-backend", "test", + "--gas", + "2000000", "--yes", ], )?; @@ -37,12 +41,37 @@ pub fn submit_consumer_chain_proposal( Ok(()) } +pub fn query_consumer_proposal( + chain_id: &str, + command_path: &str, + home_path: &str, + rpc_listen_address: &str, +) -> Result { + simple_exec( + chain_id, + command_path, + &[ + "--home", + home_path, + "--node", + rpc_listen_address, + "query", + "gov", + "proposal", + "1", + "--output", + "json", + ], + ) +} + pub fn query_consumer_genesis( chain_id: &str, command_path: &str, home_path: &str, rpc_listen_address: &str, consumer_chain_id: &str, + consumer_command_path: &str, ) -> Result { let exec_output = simple_exec( chain_id, @@ -61,7 +90,19 @@ pub fn query_consumer_genesis( ], )?; - Ok(exec_output.stdout) + // Neutron does not have the `PreCCV` configuration in its genesis file, + // and will panic due to an unknown configuration if it is set + let consumer_genesis = if consumer_command_path == "neutrond" { + let mut queried_genesis: HashMap = + serde_json::from_str(&exec_output.stdout).expect("failed to read file"); + + queried_genesis.remove("preCCV"); + serde_json::to_string(&queried_genesis).unwrap() + } else { + exec_output.stdout + }; + + Ok(consumer_genesis) } pub fn replace_genesis_state(chain_id: &str, home_path: &str) -> Result { diff --git a/tools/test-framework/src/chain/ext/bootstrap.rs b/tools/test-framework/src/chain/ext/bootstrap.rs index 8e0dee8e35..72fc668e38 100644 --- a/tools/test-framework/src/chain/ext/bootstrap.rs +++ b/tools/test-framework/src/chain/ext/bootstrap.rs @@ -5,6 +5,7 @@ use serde_json as json; use std::fs; use std::path::PathBuf; use std::str; +use std::time::Duration; use toml; use tracing::debug; @@ -15,13 +16,14 @@ use crate::chain::cli::bootstrap::{ start_chain, }; use crate::chain::cli::provider::{ - copy_validator_key_pair, query_consumer_genesis, replace_genesis_state, - submit_consumer_chain_proposal, + copy_validator_key_pair, query_consumer_genesis, query_consumer_proposal, + replace_genesis_state, submit_consumer_chain_proposal, }; use crate::chain::driver::ChainDriver; use crate::chain::exec::simple_exec; use crate::error::{handle_generic_error, Error}; use crate::ibc::token::Token; +use crate::prelude::assert_eventually_succeed; use crate::types::process::ChildProcess; use crate::types::wallet::{Wallet, WalletAddress, WalletId}; @@ -107,6 +109,28 @@ pub trait ChainBootstrapMethodsExt { spawn_time: &str, ) -> Result<(), Error>; + /** + Assert that the consumer chain proposal is eventually submitted. + */ + fn assert_consumer_chain_proposal_submitted( + &self, + chain_id: &str, + command_path: &str, + home_path: &str, + rpc_listen_address: &str, + ) -> Result<(), Error>; + + /** + Assert that the consumer chain proposal eventually passes. + */ + fn assert_consumer_chain_proposal_passed( + &self, + chain_id: &str, + command_path: &str, + home_path: &str, + rpc_listen_address: &str, + ) -> Result<(), Error>; + /** Query a consumer chain's genesis. */ @@ -277,17 +301,19 @@ impl ChainBootstrapMethodsExt for ChainDriver { "description": "First consumer chain", "chain_id": "{consumer_chain_id}", "initial_height": { + "revision_number": 1, "revision_height": 1 }, "genesis_hash": "Z2VuX2hhc2g=", "binary_hash": "YmluX2hhc2g=", "spawn_time": "{spawn_time}", - "unbonding_period": 100000000000, - "ccv_timeout_period": 100000000000, - "transfer_timeout_period": 100000000000, - "consumer_redistribution_fraction": "0.75", "blocks_per_distribution_transmission": 10, + "consumer_redistribution_fraction": "0.75", + "distribution_transmission_channel": "", "historical_entries": 10000, + "transfer_timeout_period": 100000000000, + "ccv_timeout_period": 100000000000, + "unbonding_period": 100000000000, "deposit": "10000001stake" }"#; @@ -304,6 +330,71 @@ impl ChainBootstrapMethodsExt for ChainDriver { ) } + fn assert_consumer_chain_proposal_submitted( + &self, + chain_id: &str, + command_path: &str, + home_path: &str, + rpc_listen_address: &str, + ) -> Result<(), Error> { + assert_eventually_succeed( + "consumer chain proposal submitted", + 10, + Duration::from_secs(1), + || { + match query_consumer_proposal(chain_id, command_path, home_path, rpc_listen_address) { + Ok(exec_output) => { + let json_res = json::from_str::(&exec_output.stdout).map_err(handle_generic_error)?; + let proposal_status = json_res.get("status") + .ok_or_else(|| eyre!("expected `status` field"))? + .as_str() + .ok_or_else(|| eyre!("expected string field"))?; + if proposal_status == "PROPOSAL_STATUS_VOTING_PERIOD" { + Ok(()) + } else { + Err(Error::generic(eyre!("consumer chain proposal is not in voting period. Proposal status: {proposal_status}"))) + } + }, + Err(e) => Err(Error::generic(eyre!("Error querying the consumer chain proposal. Potential issues could be due to not using enough gas or the proposal submitted is invalid. Error: {e}"))), + } + }, + )?; + Ok(()) + } + + fn assert_consumer_chain_proposal_passed( + &self, + chain_id: &str, + command_path: &str, + home_path: &str, + rpc_listen_address: &str, + ) -> Result<(), Error> { + assert_eventually_succeed( + "consumer chain proposal passed", + 10, + Duration::from_secs(5), + || { + match query_consumer_proposal(chain_id, command_path, home_path, rpc_listen_address) { + Ok(exec_output) => { + let json_res = json::from_str::(&exec_output.stdout).map_err(handle_generic_error)?; + let proposal_status = json_res.get("status") + .ok_or_else(|| eyre!("expected `status` field"))? + .as_str() + .ok_or_else(|| eyre!("expected string field"))?; + + if proposal_status == "PROPOSAL_STATUS_PASSED" { + Ok(()) + } else { + Err(Error::generic(eyre!("consumer chain proposal has not passed. Proposal status: {proposal_status}"))) + } + }, + Err(e) => Err(Error::generic(eyre!("Error querying the consumer chain proposal. Potential issues could be due to not using enough gas or the proposal submitted is invalid. Error: {e}"))), + } + }, + )?; + Ok(()) + } + fn query_consumer_genesis( &self, consumer_chain_driver: &ChainDriver, @@ -315,6 +406,7 @@ impl ChainBootstrapMethodsExt for ChainDriver { &self.home_path, &self.rpc_listen_address(), consumer_chain_id, + &consumer_chain_driver.command_path, )?; consumer_chain_driver.write_file("config/consumer_genesis.json", &consumer_genesis)?; diff --git a/tools/test-framework/src/framework/binary/ics.rs b/tools/test-framework/src/framework/binary/ics.rs index 88959ec8ee..8287353872 100644 --- a/tools/test-framework/src/framework/binary/ics.rs +++ b/tools/test-framework/src/framework/binary/ics.rs @@ -1,6 +1,4 @@ use std::str::FromStr; -use std::thread; -use std::time::Duration; use crate::bootstrap::consumer::bootstrap_consumer_node; use crate::bootstrap::single::bootstrap_single_node; @@ -74,7 +72,14 @@ where .chain_driver .submit_consumer_chain_proposal(chain_id.as_str(), "2023-05-31T12:09:47.048227Z")?; - thread::sleep(Duration::from_secs(2)); + node_a + .chain_driver + .assert_consumer_chain_proposal_submitted( + node_a.chain_driver.chain_id.as_str(), + &node_a.chain_driver.command_path, + &node_a.chain_driver.home_path, + &node_a.chain_driver.rpc_listen_address(), + )?; vote_proposal( node_a.chain_driver.chain_id.as_str(), @@ -84,7 +89,12 @@ where "1200stake", )?; - thread::sleep(Duration::from_secs(30)); + node_a.chain_driver.assert_consumer_chain_proposal_passed( + node_a.chain_driver.chain_id.as_str(), + &node_a.chain_driver.command_path, + &node_a.chain_driver.home_path, + &node_a.chain_driver.rpc_listen_address(), + )?; let node_b = bootstrap_consumer_node( builder,