Skip to content
This repository has been archived by the owner on Jan 11, 2024. It is now read-only.

Commit

Permalink
add validator info
Browse files Browse the repository at this point in the history
  • Loading branch information
cryptoAtwill committed Nov 3, 2023
1 parent 6d69633 commit 2582069
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 5 deletions.
4 changes: 4 additions & 0 deletions ipc/cli/src/commands/subnet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub use crate::commands::subnet::leave::{LeaveSubnet, LeaveSubnetArgs};
use crate::commands::subnet::list_subnets::{ListSubnets, ListSubnetsArgs};
use crate::commands::subnet::rpc::{RPCSubnet, RPCSubnetArgs};
use crate::commands::subnet::send_value::{SendValue, SendValueArgs};
use crate::commands::subnet::validator::{ValidatorInfo, ValidatorInfoArgs};
use crate::{CommandLineHandler, GlobalArguments};
use clap::{Args, Subcommand};

Expand All @@ -26,6 +27,7 @@ pub mod leave;
pub mod list_subnets;
pub mod rpc;
pub mod send_value;
mod validator;

#[derive(Debug, Args)]
#[command(
Expand Down Expand Up @@ -55,6 +57,7 @@ impl SubnetCommandsArgs {
Commands::AddBootstrap(args) => AddBootstrap::handle(global, args).await,
Commands::ListBootstraps(args) => ListBootstraps::handle(global, args).await,
Commands::GenesisEpoch(args) => GenesisEpoch::handle(global, args).await,
Commands::GetValidator(args) => ValidatorInfo::handle(global, args).await,
}
}
}
Expand All @@ -75,4 +78,5 @@ pub(crate) enum Commands {
AddBootstrap(AddBootstrapArgs),
ListBootstraps(ListBootstrapsArgs),
GenesisEpoch(GenesisEpochArgs),
GetValidator(ValidatorInfoArgs),
}
42 changes: 42 additions & 0 deletions ipc/cli/src/commands/subnet/validator.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright 2022-2023 Protocol Labs
// SPDX-License-Identifier: MIT
//! Get the validator information
use async_trait::async_trait;
use clap::Args;
use fvm_shared::address::Address;
use ipc_sdk::subnet_id::SubnetID;
use std::fmt::Debug;
use std::str::FromStr;

use crate::{get_ipc_provider, CommandLineHandler, GlobalArguments};

/// The command to get the validator information
pub(crate) struct ValidatorInfo;

#[async_trait]
impl CommandLineHandler for ValidatorInfo {
type Arguments = ValidatorInfoArgs;

async fn handle(global: &GlobalArguments, arguments: &Self::Arguments) -> anyhow::Result<()> {
log::debug!("get validator info with args: {:?}", arguments);

let provider = get_ipc_provider(global)?;
let subnet = SubnetID::from_str(&arguments.subnet)?;
let validator = Address::from_str(&arguments.validator)?;

let validator_info = provider.get_validator_info(&subnet, &validator).await?;
println!("{}", validator_info);

Ok(())
}
}

#[derive(Debug, Args)]
#[command(name = "validator-info", about = "Get the validator info")]
pub(crate) struct ValidatorInfoArgs {
#[arg(long, short, help = "The subnet id to query validator info")]
pub subnet: String,
#[arg(long, short, help = "The validator address")]
pub validator: String,
}
17 changes: 16 additions & 1 deletion ipc/provider/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use ipc_identity::{
EthKeyAddress, EvmKeyStore, KeyStore, KeyStoreConfig, PersistentKeyStore, Wallet,
};
use ipc_sdk::checkpoint::{BottomUpCheckpointBundle, QuorumReachedEvent};
use ipc_sdk::staking::StakingChangeRequest;
use ipc_sdk::staking::{StakingChangeRequest, ValidatorInfo};
use ipc_sdk::{
cross::CrossMsg,
subnet::{ConsensusType, ConstructParams},
Expand Down Expand Up @@ -604,6 +604,21 @@ impl IpcProvider {
conn.manager().genesis_epoch(subnet).await
}

/// Get the validator information.
pub async fn get_validator_info(
&self,
subnet: &SubnetID,
validator: &Address,
) -> anyhow::Result<ValidatorInfo> {
let parent = subnet.parent().ok_or_else(|| anyhow!("no parent found"))?;
let conn = match self.connection(&parent) {
None => return Err(anyhow!("target subnet parent not found")),
Some(conn) => conn,
};

conn.manager().get_validator_info(subnet, validator).await
}

/// Get the changes in subnet validators. This is fetched from parent.
pub async fn get_validator_changeset(
&self,
Expand Down
25 changes: 24 additions & 1 deletion ipc/provider/src/manager/evm/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ use ipc_identity::{EthKeyAddress, EvmKeyStore, PersistentKeyStore};
use ipc_sdk::checkpoint::{BottomUpCheckpoint, BottomUpCheckpointBundle, QuorumReachedEvent};
use ipc_sdk::cross::CrossMsg;
use ipc_sdk::gateway::Status;
use ipc_sdk::staking::StakingChangeRequest;
use ipc_sdk::staking::{StakingChangeRequest, ValidatorInfo, ValidatorStakingInfo};
use ipc_sdk::subnet::ConstructParams;
use ipc_sdk::subnet_id::SubnetID;
use num_traits::ToPrimitive;
Expand Down Expand Up @@ -744,6 +744,29 @@ impl SubnetManager for EthSubnetManager {
);
Ok(contract.get_bootstrap_nodes().call().await?)
}

async fn get_validator_info(
&self,
subnet: &SubnetID,
validator: &Address,
) -> Result<ValidatorInfo> {
let address = contract_address_from_subnet(subnet)?;
let contract = subnet_actor_getter_facet::SubnetActorGetterFacet::new(
address,
Arc::new(self.ipc_contract_info.provider.clone()),
);
let validator = payload_to_evm_address(validator.payload())?;

let validator_info = contract.get_validator(validator).call().await?;
let is_active = contract.is_active_validator(validator).call().await?;
let is_waiting = contract.is_waiting_validator(validator).call().await?;

Ok(ValidatorInfo {
staking: ValidatorStakingInfo::try_from(validator_info)?,
is_active,
is_waiting,
})
}
}

#[async_trait]
Expand Down
9 changes: 8 additions & 1 deletion ipc/provider/src/manager/subnet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use fvm_shared::clock::ChainEpoch;
use fvm_shared::{address::Address, econ::TokenAmount};
use ipc_sdk::checkpoint::{BottomUpCheckpointBundle, QuorumReachedEvent};
use ipc_sdk::cross::CrossMsg;
use ipc_sdk::staking::StakingChangeRequest;
use ipc_sdk::staking::{StakingChangeRequest, ValidatorInfo};
use ipc_sdk::subnet::ConstructParams;
use ipc_sdk::subnet_id::SubnetID;
use ipc_sdk::validator::Validator;
Expand Down Expand Up @@ -139,6 +139,13 @@ pub trait SubnetManager: Send + Sync + TopDownCheckpointQuery + BottomUpCheckpoi

/// Lists the bootstrap nodes of a subnet
async fn list_bootstrap_nodes(&self, subnet: &SubnetID) -> Result<Vec<String>>;

/// Get the validator information
async fn get_validator_info(
&self,
subnet: &SubnetID,
validator: &Address,
) -> Result<ValidatorInfo>;
}

#[derive(Debug)]
Expand Down
59 changes: 57 additions & 2 deletions ipc/sdk/src/staking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@

//! Staking module related types and functions
use crate::ethers_address_to_fil_address;
use crate::{eth_to_fil_amount, ethers_address_to_fil_address};
use ethers::utils::hex;
use fvm_shared::address::Address;
use ipc_actors_abis::lib_staking_change_log;
use fvm_shared::econ::TokenAmount;
use ipc_actors_abis::{lib_staking_change_log, subnet_actor_getter_facet};
use std::fmt::{Display, Formatter};

pub type ConfigurationNumber = u64;

Expand Down Expand Up @@ -56,3 +59,55 @@ impl TryFrom<lib_staking_change_log::NewStakingChangeRequestFilter> for StakingC
})
}
}

/// The staking validator information
#[derive(Clone, Debug)]
pub struct ValidatorStakingInfo {
confirmed_collateral: TokenAmount,
total_collateral: TokenAmount,
metadata: Vec<u8>,
}

impl Display for ValidatorStakingInfo {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"ValidatorStaking(confirmed_collateral: {}, total_collateral: {}, metadata: 0x{})",
self.confirmed_collateral,
self.total_collateral,
hex::encode(&self.metadata)
)
}
}

impl TryFrom<subnet_actor_getter_facet::ValidatorInfo> for ValidatorStakingInfo {
type Error = anyhow::Error;

fn try_from(value: subnet_actor_getter_facet::ValidatorInfo) -> Result<Self, Self::Error> {
Ok(Self {
confirmed_collateral: eth_to_fil_amount(&value.confirmed_collateral)?,
total_collateral: eth_to_fil_amount(&value.total_collateral)?,
metadata: value.metadata.to_vec(),
})
}
}

/// The full validator information with
#[derive(Clone, Debug)]
pub struct ValidatorInfo {
pub staking: ValidatorStakingInfo,
/// If the validator is active in block production
pub is_active: bool,
/// If the validator is current waiting to be promoted to active
pub is_waiting: bool,
}

impl Display for ValidatorInfo {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(
f,
"ValidatorInfo(staking: {}, is_active: {}, is_waiting: {})",
self.staking, self.is_active, self.is_waiting
)
}
}

0 comments on commit 2582069

Please sign in to comment.