diff --git a/api/bin/chainflip-cli/src/main.rs b/api/bin/chainflip-cli/src/main.rs index 47de1818c7c..9664a4f058e 100644 --- a/api/bin/chainflip-cli/src/main.rs +++ b/api/bin/chainflip-cli/src/main.rs @@ -124,6 +124,9 @@ async fn run_cli() -> Result<()> { VanityName { name } => { api.operator_api().set_vanity_name(name).await?; }, + CheckUpdate {} => { + get_update_state(api.query_api()).await? + } ForceRotation {} => { api.governance_api().force_rotation().await?; }, @@ -291,6 +294,17 @@ async fn get_bound_executor_address(api: QueryApi) -> Result<()> { Ok(()) } +async fn get_update_state(api: QueryApi) -> Result<()> { + let can_update = api.get_update_state(None, None).await?; + if can_update { + println!("You can safely update your node/engine"); + } else { + println!("A rotation is in progress and you are an Authority, please wait till the end of the rotation to update your node/engine"); + } + + Ok(()) +} + fn confirm_submit() -> bool { use std::{io, io::*}; diff --git a/api/bin/chainflip-cli/src/settings.rs b/api/bin/chainflip-cli/src/settings.rs index 7e8e628d47d..09a1fc621f9 100644 --- a/api/bin/chainflip-cli/src/settings.rs +++ b/api/bin/chainflip-cli/src/settings.rs @@ -150,6 +150,8 @@ pub enum CliCommand { #[clap(help = "Name in UTF-8 (max length 64)")] name: String, }, + #[clap(about = "Check if it is safe to update your node/engine")] + CheckUpdate {}, #[clap( // This is only useful for testing. No need to show to the end user. hide = true, diff --git a/api/lib/src/queries.rs b/api/lib/src/queries.rs index 2da798e5923..b5d3cef399c 100644 --- a/api/lib/src/queries.rs +++ b/api/lib/src/queries.rs @@ -5,6 +5,7 @@ use chainflip_engine::state_chain_observer::client::{ chain_api::ChainApi, storage_api::StorageApi, }; use pallet_cf_ingress_egress::DepositChannelDetails; +use pallet_cf_validator::RotationPhase; use serde::Deserialize; use state_chain_runtime::PalletInstanceAlias; use std::{collections::BTreeMap, sync::Arc}; @@ -143,4 +144,23 @@ impl QueryApi { ) .await?) } + + pub async fn get_update_state(&self, block_hash: Option, account_id: Option) -> Result { + let block_hash = + block_hash.unwrap_or_else(|| self.state_chain_client.latest_finalized_hash()); + let account_id = account_id.unwrap_or_else(|| self.state_chain_client.account_id()); + + if self.state_chain_client.storage_value::>(block_hash).await? == RotationPhase::Idle{ + return Ok(true); + } + + let current_validators = self.state_chain_client.storage_value::>(block_hash).await?; + for validator in current_validators.iter() { + if account_id == *validator { + return Ok(false); + } + } + + Ok(true) + } }