From 966cc133bd8f7bc753e31333f909931403900db0 Mon Sep 17 00:00:00 2001 From: Alfonso de la Rocha Date: Fri, 8 Sep 2023 12:14:23 +0200 Subject: [PATCH 1/4] ipc-299: implement subnet cli commands --- ipc/cli/src/commands/subnet/create.rs | 4 +- ipc/cli/src/commands/subnet/join.rs | 45 ++++++----- ipc/cli/src/commands/subnet/kill.rs | 27 +++---- ipc/cli/src/commands/subnet/leave.rs | 29 +++---- ipc/cli/src/commands/subnet/list_subnets.rs | 63 ++++----------- .../src/commands/subnet/list_validators.rs | 36 ++++----- ipc/cli/src/commands/subnet/mod.rs | 77 +++++++++---------- ipc/cli/src/commands/subnet/net_addr.rs | 42 ++++------ ipc/cli/src/commands/subnet/rpc.rs | 33 ++------ ipc/cli/src/commands/subnet/send_value.rs | 48 ++++++------ ipc/cli/src/commands/subnet/worker_addr.rs | 44 ++++------- 11 files changed, 174 insertions(+), 274 deletions(-) diff --git a/ipc/cli/src/commands/subnet/create.rs b/ipc/cli/src/commands/subnet/create.rs index e75baa91..3f5e61d5 100644 --- a/ipc/cli/src/commands/subnet/create.rs +++ b/ipc/cli/src/commands/subnet/create.rs @@ -31,7 +31,7 @@ impl CreateSubnet { let addr = provider .create_subnet( from, - &parent, + parent, arguments.name.clone(), arguments.min_validators, f64_to_token_amount(arguments.min_validator_stake)?, @@ -66,8 +66,6 @@ impl CommandLineHandler for CreateSubnet { #[derive(Debug, Args)] #[command(name = "create", about = "Create a new subnet actor")] pub struct CreateSubnetArgs { - #[arg(long, short, help = "The JSON RPC server url for ipc agent")] - pub ipc_agent_url: Option, #[arg(long, short, help = "The address that creates the subnet")] pub from: Option, #[arg(long, short, help = "The parent subnet to create the new actor in")] diff --git a/ipc/cli/src/commands/subnet/join.rs b/ipc/cli/src/commands/subnet/join.rs index ff9d3b19..17e6a99e 100644 --- a/ipc/cli/src/commands/subnet/join.rs +++ b/ipc/cli/src/commands/subnet/join.rs @@ -4,12 +4,11 @@ use async_trait::async_trait; use clap::Args; -use std::fmt::Debug; +use fvm_shared::address::Address; +use ipc_sdk::subnet_id::SubnetID; +use std::{fmt::Debug, str::FromStr}; -use crate::commands::get_ipc_agent_url; -use crate::sdk::IpcAgentClient; -use crate::server::join::JoinSubnetParams; -use crate::{CommandLineHandler, GlobalArguments}; +use crate::{f64_to_token_amount, get_ipc_provider, CommandLineHandler, GlobalArguments}; /// The command to join a subnet pub struct JoinSubnet; @@ -21,32 +20,32 @@ impl CommandLineHandler for JoinSubnet { async fn handle(global: &GlobalArguments, arguments: &Self::Arguments) -> anyhow::Result<()> { log::debug!("join subnet with args: {:?}", arguments); - let url = get_ipc_agent_url(&arguments.ipc_agent_url, global)?; - - // The json rpc server will handle directing the request to - // the correct parent. - let params = JoinSubnetParams { - subnet: arguments.subnet.clone(), - from: arguments.from.clone(), - collateral: arguments.collateral, - validator_net_addr: arguments.validator_net_addr.clone(), - worker_addr: arguments.worker_addr.clone(), + let mut provider = get_ipc_provider(global)?; + let subnet = SubnetID::from_str(&arguments.subnet)?; + let from = match &arguments.from { + Some(address) => Some(Address::from_str(address)?), + None => None, + }; + let worker_addr = match &arguments.worker_addr { + Some(address) => Some(Address::from_str(address)?), + None => None, }; - let client = IpcAgentClient::default_from_url(url); - client.join_subnet(params).await?; - - log::info!("joined subnet: {:}", arguments.subnet); - - Ok(()) + provider + .join_subnet( + subnet, + from, + f64_to_token_amount(arguments.collateral)?, + arguments.validator_net_addr.clone(), + worker_addr, + ) + .await } } #[derive(Debug, Args)] #[command(name = "join", about = "Join a subnet")] pub struct JoinSubnetArgs { - #[arg(long, short, help = "The JSON RPC server url for ipc agent")] - pub ipc_agent_url: Option, #[arg(long, short, help = "The address that joins the subnet")] pub from: Option, #[arg(long, short, help = "The subnet to join")] diff --git a/ipc/cli/src/commands/subnet/kill.rs b/ipc/cli/src/commands/subnet/kill.rs index 96772422..42afe0ad 100644 --- a/ipc/cli/src/commands/subnet/kill.rs +++ b/ipc/cli/src/commands/subnet/kill.rs @@ -4,12 +4,11 @@ use async_trait::async_trait; use clap::Args; -use std::fmt::Debug; +use fvm_shared::address::Address; +use ipc_sdk::subnet_id::SubnetID; +use std::{fmt::Debug, str::FromStr}; -use crate::commands::get_ipc_agent_url; -use crate::sdk::IpcAgentClient; -use crate::server::kill::KillSubnetParams; -use crate::{CommandLineHandler, GlobalArguments}; +use crate::{get_ipc_provider, CommandLineHandler, GlobalArguments}; /// The command to kill an existing subnet. pub struct KillSubnet; @@ -21,26 +20,20 @@ impl CommandLineHandler for KillSubnet { async fn handle(global: &GlobalArguments, arguments: &Self::Arguments) -> anyhow::Result<()> { log::debug!("kill subnet with args: {:?}", arguments); - let params = KillSubnetParams { - subnet: arguments.subnet.clone(), - from: arguments.from.clone(), + let mut provider = get_ipc_provider(global)?; + let subnet = SubnetID::from_str(&arguments.subnet)?; + let from = match &arguments.from { + Some(address) => Some(Address::from_str(address)?), + None => None, }; - let url = get_ipc_agent_url(&arguments.ipc_agent_url, global)?; - let client = IpcAgentClient::default_from_url(url); - client.kill_subnet(params).await?; - - log::info!("killed subnet: {:}", arguments.subnet); - - Ok(()) + provider.kill_subnet(subnet, from).await } } #[derive(Debug, Args)] #[command(name = "kill", about = "Kill an existing subnet")] pub struct KillSubnetArgs { - #[arg(long, short, help = "The JSON RPC server url for ipc agent")] - pub ipc_agent_url: Option, #[arg(long, short, help = "The address that kills the subnet")] pub from: Option, #[arg(long, short, help = "The subnet to kill")] diff --git a/ipc/cli/src/commands/subnet/leave.rs b/ipc/cli/src/commands/subnet/leave.rs index 015a7bcd..e25ac089 100644 --- a/ipc/cli/src/commands/subnet/leave.rs +++ b/ipc/cli/src/commands/subnet/leave.rs @@ -4,12 +4,11 @@ use async_trait::async_trait; use clap::Args; -use std::fmt::Debug; +use fvm_shared::address::Address; +use ipc_sdk::subnet_id::SubnetID; +use std::{fmt::Debug, str::FromStr}; -use crate::commands::get_ipc_agent_url; -use crate::sdk::IpcAgentClient; -use crate::server::leave::LeaveSubnetParams; -use crate::{CommandLineHandler, GlobalArguments}; +use crate::{get_ipc_provider, CommandLineHandler, GlobalArguments}; /// The command to leave a new subnet. pub struct LeaveSubnet; @@ -21,27 +20,19 @@ impl CommandLineHandler for LeaveSubnet { async fn handle(global: &GlobalArguments, arguments: &Self::Arguments) -> anyhow::Result<()> { log::debug!("leave subnet with args: {:?}", arguments); - let params = LeaveSubnetParams { - subnet: arguments.subnet.clone(), - from: arguments.from.clone(), + let mut provider = get_ipc_provider(global)?; + let subnet = SubnetID::from_str(&arguments.subnet)?; + let from = match &arguments.from { + Some(address) => Some(Address::from_str(address)?), + None => None, }; - - let url = get_ipc_agent_url(&arguments.ipc_agent_url, global)?; - - let client = IpcAgentClient::default_from_url(url); - client.leave_subnet(params).await?; - - log::info!("left subnet: {:}", arguments.subnet); - - Ok(()) + provider.leave_subnet(subnet, from).await } } #[derive(Debug, Args)] #[command(name = "leave", about = "Leaving a subnet")] pub struct LeaveSubnetArgs { - #[arg(long, short, help = "The JSON RPC server url for ipc agent")] - pub ipc_agent_url: Option, #[arg(long, short, help = "The address that leaves the subnet")] pub from: Option, #[arg(long, short, help = "The subnet to leave")] diff --git a/ipc/cli/src/commands/subnet/list_subnets.rs b/ipc/cli/src/commands/subnet/list_subnets.rs index bce04969..f0b1a75d 100644 --- a/ipc/cli/src/commands/subnet/list_subnets.rs +++ b/ipc/cli/src/commands/subnet/list_subnets.rs @@ -4,18 +4,12 @@ use async_trait::async_trait; use clap::Args; -use fvm_shared::bigint::BigInt; -use fvm_shared::econ::TokenAmount; -use std::collections::HashMap; +use fvm_shared::{address::Address, econ::TokenAmount}; +use ipc_sdk::subnet_id::SubnetID; use std::fmt::Debug; use std::str::FromStr; -use crate::commands::get_ipc_agent_url; -use crate::config::json_rpc_methods; -use crate::server::list_subnets::ListSubnetsParams; -use crate::{CommandLineHandler, GlobalArguments}; -use ipc_provider::jsonrpc::{JsonRpcClient, JsonRpcClientImpl}; -use serde::Deserialize; +use crate::{get_ipc_provider, CommandLineHandler, GlobalArguments}; /// The command to create a new subnet actor. pub(crate) struct ListSubnets; @@ -27,32 +21,23 @@ impl CommandLineHandler for ListSubnets { async fn handle(global: &GlobalArguments, arguments: &Self::Arguments) -> anyhow::Result<()> { log::debug!("list subnets with args: {:?}", arguments); - let url = get_ipc_agent_url(&arguments.ipc_agent_url, global)?; - let json_rpc_client = JsonRpcClientImpl::new(url, None); + let provider = get_ipc_provider(global)?; + let subnet = SubnetID::from_str(&arguments.subnet)?; - let params = ListSubnetsParams { - gateway_address: arguments.gateway_address.clone(), - subnet_id: arguments.subnet.clone(), + let gateway_addr = match &arguments.gateway_address { + Some(address) => Some(Address::from_str(address)?), + None => None, }; - let subnets = json_rpc_client - .request::>( - json_rpc_methods::LIST_CHILD_SUBNETS, - serde_json::to_value(params)?, - ) - .await?; + let ls = provider.list_child_subnets(gateway_addr, &subnet).await?; - for (_, s) in subnets.iter() { - let u = BigInt::from_str(&s.stake).unwrap(); - let stake = TokenAmount::from_atto(u); - let u = BigInt::from_str(&s.circ_supply).unwrap(); - let supply = TokenAmount::from_atto(u); - log::info!( - "{} - status: {}, collateral: {} FIL, circ.supply: {} FIL", + for (_, s) in ls.iter() { + println!( + "{:?} - status: {:?}, collateral: {:?} FIL, circ.supply: {:?} FIL", s.id, s.status, - stake, - supply, + TokenAmount::from_whole(s.stake.atto().clone()), + TokenAmount::from_whole(s.circ_supply.atto().clone()), ); } @@ -66,26 +51,8 @@ impl CommandLineHandler for ListSubnets { about = "List all child subnets registered in the gateway (i.e. that have provided enough collateral)" )] pub(crate) struct ListSubnetsArgs { - #[arg(long, short, help = "The JSON RPC server url for ipc agent")] - pub ipc_agent_url: Option, #[arg(long, short, help = "The gateway address to query subnets")] - pub gateway_address: String, + pub gateway_address: Option, #[arg(long, short, help = "The subnet id to query child subnets")] pub subnet: String, } - -/// A simplified wrapper for Subnet Info response. The SubnetInfo struct is deserialized differently -/// as that struct is targeting deserialization from Actor. SubnetInfoWrapper is targeting ipc-agent -/// rpc server, it is using different data structure and casing, i.e. id in actor is represented as -/// a map, but in ipc-agent rpc server, it is a string. -#[derive(Debug, Deserialize)] -struct SubnetInfoWrapper { - #[allow(dead_code)] - id: String, - #[allow(dead_code)] - stake: String, - #[allow(dead_code)] - circ_supply: String, - #[allow(dead_code)] - status: i32, -} diff --git a/ipc/cli/src/commands/subnet/list_validators.rs b/ipc/cli/src/commands/subnet/list_validators.rs index 5fc830ad..e32e3d21 100644 --- a/ipc/cli/src/commands/subnet/list_validators.rs +++ b/ipc/cli/src/commands/subnet/list_validators.rs @@ -4,14 +4,11 @@ use async_trait::async_trait; use clap::Args; -use ipc_provider::jsonrpc::{JsonRpcClient, JsonRpcClientImpl}; -use std::fmt::Debug; +use fvm_shared::address::Address; +use ipc_sdk::subnet_id::SubnetID; +use std::{fmt::Debug, str::FromStr}; -use crate::commands::get_ipc_agent_url; -use crate::config::json_rpc_methods; -use crate::lotus::message::ipc::QueryValidatorSetResponse; -use crate::server::query_validators::QueryValidatorSetParams; -use crate::{CommandLineHandler, GlobalArguments}; +use crate::{get_ipc_provider, CommandLineHandler, GlobalArguments}; /// The command to create a new subnet actor. pub(crate) struct ListValidators; @@ -23,23 +20,20 @@ impl CommandLineHandler for ListValidators { async fn handle(global: &GlobalArguments, arguments: &Self::Arguments) -> anyhow::Result<()> { log::debug!("list validators with args: {:?}", arguments); - let url = get_ipc_agent_url(&arguments.ipc_agent_url, global)?; - let json_rpc_client = JsonRpcClientImpl::new(url, None); + let provider = get_ipc_provider(global)?; + let subnet = SubnetID::from_str(&arguments.subnet)?; - let params = QueryValidatorSetParams { - subnet: arguments.subnet.clone(), - epoch: None, + let gateway_addr = match &arguments.gateway_address { + Some(address) => Some(Address::from_str(address)?), + None => None, }; - let valset = json_rpc_client - .request::( - json_rpc_methods::QUERY_VALIDATOR_SET, - serde_json::to_value(params)?, - ) + let valset = provider + .get_validator_set(&subnet, gateway_addr, None) .await?; - log::info!("validators number: {}", valset.min_validators); - log::info!("validator set: {:?}", valset.validator_set); + println!("minimum number of validators: {}", valset.min_validators); + println!("validator set: {:?}", valset.validator_set); Ok(()) } @@ -48,8 +42,8 @@ impl CommandLineHandler for ListValidators { #[derive(Debug, Args)] #[command(name = "list-validators", about = "Show the validators of the subnet")] pub(crate) struct ListValidatorsArgs { - #[arg(long, short, help = "The JSON RPC server url for ipc agent")] - pub ipc_agent_url: Option, + #[arg(long, short, help = "The gateway address to query subnets")] + pub gateway_address: Option, #[arg(long, short, help = "The subnet id to query validators")] pub subnet: String, } diff --git a/ipc/cli/src/commands/subnet/mod.rs b/ipc/cli/src/commands/subnet/mod.rs index 9057ec80..1f958b02 100644 --- a/ipc/cli/src/commands/subnet/mod.rs +++ b/ipc/cli/src/commands/subnet/mod.rs @@ -2,29 +2,28 @@ // SPDX-License-Identifier: MIT pub use crate::commands::subnet::create::{CreateSubnet, CreateSubnetArgs}; -// pub use crate::commands::subnet::join::{JoinSubnet, JoinSubnetArgs}; -// pub use crate::commands::subnet::kill::{KillSubnet, KillSubnetArgs}; -// pub use crate::commands::subnet::leave::{LeaveSubnet, LeaveSubnetArgs}; -// use crate::commands::subnet::list_subnets::{ListSubnets, ListSubnetsArgs}; -// use crate::commands::subnet::list_validators::{ListValidators, ListValidatorsArgs}; -// use crate::commands::subnet::net_addr::{SetValidatorNetAddr, SetValidatorNetAddrArgs}; -// use crate::commands::subnet::send_value::{SendValue, SendValueArgs}; -// use crate::commands::subnet::worker_addr::{SetValidatorWorkerAddr, SetValidatorWorkerAddrArgs}; +pub use crate::commands::subnet::join::{JoinSubnet, JoinSubnetArgs}; +pub use crate::commands::subnet::kill::{KillSubnet, KillSubnetArgs}; +pub use crate::commands::subnet::leave::{LeaveSubnet, LeaveSubnetArgs}; +use crate::commands::subnet::list_subnets::{ListSubnets, ListSubnetsArgs}; +use crate::commands::subnet::list_validators::{ListValidators, ListValidatorsArgs}; +use crate::commands::subnet::net_addr::{SetValidatorNetAddr, SetValidatorNetAddrArgs}; +use crate::commands::subnet::rpc::{RPCSubnet, RPCSubnetArgs}; +use crate::commands::subnet::send_value::{SendValue, SendValueArgs}; +use crate::commands::subnet::worker_addr::{SetValidatorWorkerAddr, SetValidatorWorkerAddrArgs}; use crate::{CommandLineHandler, GlobalArguments}; use clap::{Args, Subcommand}; -// use self::rpc::{RPCSubnet, RPCSubnetArgs}; - pub mod create; -// pub mod join; -// pub mod kill; -// pub mod leave; -// pub mod list_subnets; -// pub mod list_validators; -// pub mod net_addr; -// pub mod rpc; -// pub mod send_value; -// pub mod worker_addr; +pub mod join; +pub mod kill; +pub mod leave; +pub mod list_subnets; +pub mod list_validators; +pub mod net_addr; +pub mod rpc; +pub mod send_value; +pub mod worker_addr; #[derive(Debug, Args)] #[command( @@ -41,17 +40,17 @@ impl SubnetCommandsArgs { pub async fn handle(&self, global: &GlobalArguments) -> anyhow::Result<()> { match &self.command { Commands::Create(args) => CreateSubnet::handle(global, args).await, - // Commands::List(args) => ListSubnets::handle(global, args).await, - // Commands::ListValidators(args) => ListValidators::handle(global, args).await, - // Commands::Join(args) => JoinSubnet::handle(global, args).await, - // Commands::Rpc(args) => RPCSubnet::handle(global, args).await, - // Commands::Leave(args) => LeaveSubnet::handle(global, args).await, - // Commands::Kill(args) => KillSubnet::handle(global, args).await, - // Commands::SendValue(args) => SendValue::handle(global, args).await, - // Commands::SetValidatorNetAddr(args) => SetValidatorNetAddr::handle(global, args).await, - // Commands::SetValidatorWorkerAddr(args) => { - // SetValidatorWorkerAddr::handle(global, args).await - // } + Commands::List(args) => ListSubnets::handle(global, args).await, + Commands::ListValidators(args) => ListValidators::handle(global, args).await, + Commands::Join(args) => JoinSubnet::handle(global, args).await, + Commands::Rpc(args) => RPCSubnet::handle(global, args).await, + Commands::Leave(args) => LeaveSubnet::handle(global, args).await, + Commands::Kill(args) => KillSubnet::handle(global, args).await, + Commands::SendValue(args) => SendValue::handle(global, args).await, + Commands::SetValidatorNetAddr(args) => SetValidatorNetAddr::handle(global, args).await, + Commands::SetValidatorWorkerAddr(args) => { + SetValidatorWorkerAddr::handle(global, args).await + } } } } @@ -59,13 +58,13 @@ impl SubnetCommandsArgs { #[derive(Debug, Subcommand)] pub(crate) enum Commands { Create(CreateSubnetArgs), - // List(ListSubnetsArgs), - // ListValidators(ListValidatorsArgs), - // Join(JoinSubnetArgs), - // Rpc(RPCSubnetArgs), - // Leave(LeaveSubnetArgs), - // Kill(KillSubnetArgs), - // SendValue(SendValueArgs), - // SetValidatorNetAddr(SetValidatorNetAddrArgs), - // SetValidatorWorkerAddr(SetValidatorWorkerAddrArgs), + List(ListSubnetsArgs), + ListValidators(ListValidatorsArgs), + Join(JoinSubnetArgs), + Rpc(RPCSubnetArgs), + Leave(LeaveSubnetArgs), + Kill(KillSubnetArgs), + SendValue(SendValueArgs), + SetValidatorNetAddr(SetValidatorNetAddrArgs), + SetValidatorWorkerAddr(SetValidatorWorkerAddrArgs), } diff --git a/ipc/cli/src/commands/subnet/net_addr.rs b/ipc/cli/src/commands/subnet/net_addr.rs index 85fef5a7..051c8d1e 100644 --- a/ipc/cli/src/commands/subnet/net_addr.rs +++ b/ipc/cli/src/commands/subnet/net_addr.rs @@ -2,13 +2,14 @@ // SPDX-License-Identifier: MIT //! The command to set the validator net address -use crate::commands::get_ipc_agent_url; -use crate::config::json_rpc_methods; -use crate::server::net_addr::SetValidatorNetAddrParams; -use crate::{CommandLineHandler, GlobalArguments}; +use std::str::FromStr; + use async_trait::async_trait; use clap::Args; -use ipc_provider::jsonrpc::{JsonRpcClient, JsonRpcClientImpl}; +use fvm_shared::address::Address; +use ipc_sdk::subnet_id::SubnetID; + +use crate::{get_ipc_provider, CommandLineHandler, GlobalArguments}; /// Setting the validator net address pub(crate) struct SetValidatorNetAddr; @@ -20,37 +21,22 @@ impl CommandLineHandler for SetValidatorNetAddr { async fn handle(global: &GlobalArguments, arguments: &Self::Arguments) -> anyhow::Result<()> { log::debug!("set the validator net addr args: {:?}", arguments); - let url = get_ipc_agent_url(&arguments.ipc_agent_url, global)?; - let json_rpc_client = JsonRpcClientImpl::new(url, None); - - let params = SetValidatorNetAddrParams { - subnet: arguments.subnet.clone(), - from: arguments.from.clone(), - validator_net_addr: arguments.validator_net_addr.clone(), + let mut provider = get_ipc_provider(global)?; + let subnet = SubnetID::from_str(&arguments.subnet)?; + let from = match &arguments.from { + Some(address) => Some(Address::from_str(address)?), + None => None, }; - json_rpc_client - .request::<()>( - json_rpc_methods::SET_VALIDATOR_NET_ADDR, - serde_json::to_value(params)?, - ) - .await?; - - log::info!( - "set the validator net addr to: {:} in subnet: {:}", - arguments.validator_net_addr, - arguments.subnet - ); - - Ok(()) + provider + .set_validator_net_addr(subnet, from, arguments.validator_net_addr.clone()) + .await } } #[derive(Debug, Args)] #[command(about = "Set the validator net address")] pub(crate) struct SetValidatorNetAddrArgs { - #[arg(long, short, help = "The JSON RPC server url for ipc agent")] - pub ipc_agent_url: Option, #[arg(long, short, help = "Owner address of the validator being updated")] pub from: Option, #[arg(long, short, help = "The subnet to set the validator")] diff --git a/ipc/cli/src/commands/subnet/rpc.rs b/ipc/cli/src/commands/subnet/rpc.rs index fd018641..9d41f519 100644 --- a/ipc/cli/src/commands/subnet/rpc.rs +++ b/ipc/cli/src/commands/subnet/rpc.rs @@ -8,11 +8,7 @@ use ipc_sdk::subnet_id::SubnetID; use std::fmt::Debug; use std::str::FromStr; -use crate::commands::get_ipc_agent_url; -use crate::config::json_rpc_methods; -use crate::server::rpc::RPCSubnetParams; -use crate::{CommandLineHandler, GlobalArguments}; -use ipc_provider::jsonrpc::{JsonRpcClient, JsonRpcClientImpl}; +use crate::{get_ipc_provider, CommandLineHandler, GlobalArguments}; /// The command to get the RPC endpoint for a subnet pub struct RPCSubnet; @@ -24,28 +20,15 @@ impl CommandLineHandler for RPCSubnet { async fn handle(global: &GlobalArguments, arguments: &Self::Arguments) -> anyhow::Result<()> { log::debug!("get rpc for subnet with args: {:?}", arguments); - let url = get_ipc_agent_url(&arguments.ipc_agent_url, global)?; - let json_rpc_client = JsonRpcClientImpl::new(url, None); - - let params = RPCSubnetParams { - subnet: arguments.subnet.clone(), + let provider = get_ipc_provider(global)?; + let subnet = SubnetID::from_str(&arguments.subnet)?; + let conn = match provider.connection(&subnet) { + None => return Err(anyhow::anyhow!("target subnet not found")), + Some(conn) => conn, }; - let rpc = json_rpc_client - .request::(json_rpc_methods::RPC_SUBNET, serde_json::to_value(params)?) - .await?; - - let id = SubnetID::from_str(&arguments.subnet)?; - - log::info!("rpc endpoint for subnet {:}: {:}", arguments.subnet, rpc); - // todo: We currently have the same ChainID for all subnet. This will be changed - // once https://github.com/consensus-shipyard/lotus/issues/178 is implemented - log::info!( - "chainID for subnet {:}: {:}", - arguments.subnet, - id.chain_id(), - ); - + println!("rpc: {:?}", conn.subnet().rpc_http().to_string()); + println!("chainID: {:?}", subnet.chain_id()); Ok(()) } } diff --git a/ipc/cli/src/commands/subnet/send_value.rs b/ipc/cli/src/commands/subnet/send_value.rs index 869d41a5..8f96d48d 100644 --- a/ipc/cli/src/commands/subnet/send_value.rs +++ b/ipc/cli/src/commands/subnet/send_value.rs @@ -4,13 +4,12 @@ use async_trait::async_trait; use clap::Args; -use std::fmt::Debug; +use fvm_shared::address::Address; +use ipc_provider::manager::evm::ethers_address_to_fil_address; +use ipc_sdk::subnet_id::SubnetID; +use std::{fmt::Debug, str::FromStr}; -use crate::commands::get_ipc_agent_url; -use crate::config::json_rpc_methods; -use crate::server::send_value::SendValueParams; -use crate::{CommandLineHandler, GlobalArguments}; -use ipc_provider::jsonrpc::{JsonRpcClient, JsonRpcClientImpl}; +use crate::{f64_to_token_amount, get_ipc_provider, CommandLineHandler, GlobalArguments}; pub(crate) struct SendValue; @@ -21,33 +20,34 @@ impl CommandLineHandler for SendValue { async fn handle(global: &GlobalArguments, arguments: &Self::Arguments) -> anyhow::Result<()> { log::debug!("send value in subnet with args: {:?}", arguments); - let url = get_ipc_agent_url(&arguments.ipc_agent_url, global)?; - let json_rpc_client = JsonRpcClientImpl::new(url, None); - - // The json rpc server will handle directing the request to - // the correct parent. - let params = SendValueParams { - subnet: arguments.subnet.clone(), - from: arguments.from.clone(), - to: arguments.to.clone(), - amount: arguments.amount, + let mut provider = get_ipc_provider(global)?; + let subnet = SubnetID::from_str(&arguments.subnet)?; + let from = match &arguments.from { + Some(address) => Some(Address::from_str(address)?), + None => None, }; - json_rpc_client - .request::<()>(json_rpc_methods::SEND_VALUE, serde_json::to_value(params)?) - .await?; - - log::info!("sending value in subnet: {:}", arguments.subnet); + // try to get the `to` as an FVM address and an Eth + // address. We should include a wrapper type to make + // this easier through the whole code base. + let to = match Address::from_str(&arguments.to) { + Err(_) => { + // see if it is an eth address + let addr = ethers::types::Address::from_str(&arguments.to)?; + ethers_address_to_fil_address(&addr)? + } + Ok(addr) => addr, + }; - Ok(()) + provider + .send_value(&subnet, from, to, f64_to_token_amount(arguments.amount)?) + .await } } #[derive(Debug, Args)] #[command(about = "Send value to an address within a subnet")] pub(crate) struct SendValueArgs { - #[arg(long, short, help = "The JSON RPC server url for ipc agent")] - pub ipc_agent_url: Option, #[arg(long, short, help = "The address to send value from")] pub from: Option, #[arg(long, short, help = "The address to send value to")] diff --git a/ipc/cli/src/commands/subnet/worker_addr.rs b/ipc/cli/src/commands/subnet/worker_addr.rs index 80cf21d9..0763a21b 100644 --- a/ipc/cli/src/commands/subnet/worker_addr.rs +++ b/ipc/cli/src/commands/subnet/worker_addr.rs @@ -2,13 +2,14 @@ // SPDX-License-Identifier: MIT //! The command to set the validator worker address -use crate::commands::get_ipc_agent_url; -use crate::config::json_rpc_methods; -use crate::server::worker_addr::SetValidatorWorkerAddrParams; -use crate::{CommandLineHandler, GlobalArguments}; +use std::str::FromStr; + use async_trait::async_trait; use clap::Args; -use ipc_provider::jsonrpc::{JsonRpcClient, JsonRpcClientImpl}; +use fvm_shared::address::Address; +use ipc_sdk::subnet_id::SubnetID; + +use crate::{get_ipc_provider, CommandLineHandler, GlobalArguments}; /// Setting the validator worker address pub(crate) struct SetValidatorWorkerAddr; @@ -20,37 +21,26 @@ impl CommandLineHandler for SetValidatorWorkerAddr { async fn handle(global: &GlobalArguments, arguments: &Self::Arguments) -> anyhow::Result<()> { log::debug!("set the validator worker addr args: {:?}", arguments); - let url = get_ipc_agent_url(&arguments.ipc_agent_url, global)?; - let json_rpc_client = JsonRpcClientImpl::new(url, None); - - let params = SetValidatorWorkerAddrParams { - subnet: arguments.subnet.clone(), - from: arguments.from.clone(), - validator_worker_addr: arguments.validator_worker_addr.clone(), + let mut provider = get_ipc_provider(global)?; + let subnet = SubnetID::from_str(&arguments.subnet)?; + let from = match &arguments.from { + Some(address) => Some(Address::from_str(address)?), + None => None, }; - json_rpc_client - .request::<()>( - json_rpc_methods::SET_VALIDATOR_WORKER_ADDR, - serde_json::to_value(params)?, + provider + .set_validator_worker_addr( + subnet, + from, + Address::from_str(&arguments.validator_worker_addr)?, ) - .await?; - - log::info!( - "set the validator worker addr to: {:} in subnet: {:}", - arguments.validator_worker_addr, - arguments.subnet - ); - - Ok(()) + .await } } #[derive(Debug, Args)] #[command(about = "Set the validator worker address")] pub(crate) struct SetValidatorWorkerAddrArgs { - #[arg(long, short, help = "The JSON RPC server url for ipc agent")] - pub ipc_agent_url: Option, #[arg(long, short, help = "Owner address of the validator being updated")] pub from: Option, #[arg(long, short, help = "The subnet to set the validator")] From 236a20e92ba5197afe728477ed38c17e743f8dff Mon Sep 17 00:00:00 2001 From: Alfonso de la Rocha Date: Fri, 8 Sep 2023 12:54:36 +0200 Subject: [PATCH 2/4] ipc-299: implement cross cli commands --- ipc/cli/src/commands/crossmsg/fund.rs | 52 +++++++++++++------ ipc/cli/src/commands/crossmsg/propagate.rs | 27 +--------- ipc/cli/src/commands/crossmsg/release.rs | 52 +++++++++++++------ ipc/cli/src/commands/mod.rs | 30 +++++++---- ipc/cli/src/commands/subnet/list_subnets.rs | 6 +-- .../src/commands/subnet/list_validators.rs | 5 +- ipc/cli/src/commands/subnet/send_value.rs | 25 ++++----- ipc/provider/src/lib.rs | 12 +++-- 8 files changed, 114 insertions(+), 95 deletions(-) diff --git a/ipc/cli/src/commands/crossmsg/fund.rs b/ipc/cli/src/commands/crossmsg/fund.rs index 57eee65f..a2df865d 100644 --- a/ipc/cli/src/commands/crossmsg/fund.rs +++ b/ipc/cli/src/commands/crossmsg/fund.rs @@ -4,11 +4,14 @@ use async_trait::async_trait; use clap::Args; -use std::fmt::Debug; +use fvm_shared::address::Address; +use ipc_sdk::subnet_id::SubnetID; +use std::{fmt::Debug, str::FromStr}; -use crate::commands::get_ipc_agent_url; -use crate::sdk::IpcAgentClient; -use crate::{CommandLineHandler, GlobalArguments}; +use crate::{ + f64_to_token_amount, get_ipc_provider, require_fil_addr_from_str, CommandLineHandler, + GlobalArguments, +}; /// The command to send funds to a subnet from parent pub(crate) struct Fund; @@ -20,18 +23,33 @@ impl CommandLineHandler for Fund { async fn handle(global: &GlobalArguments, arguments: &Self::Arguments) -> anyhow::Result<()> { log::debug!("fund operation with args: {:?}", arguments); - let url = get_ipc_agent_url(&arguments.ipc_agent_url, global)?; - let client = IpcAgentClient::default_from_url(url); - let epoch = client - .fund( - &arguments.subnet, - arguments.from.clone(), - arguments.to.clone(), - arguments.amount, - ) - .await?; + let mut provider = get_ipc_provider(global)?; + let subnet = SubnetID::from_str(&arguments.subnet)?; + let from = match &arguments.from { + Some(address) => Some(Address::from_str(address)?), + None => None, + }; + let to = match &arguments.to { + Some(address) => Some(require_fil_addr_from_str(address)?), + None => None, + }; + let gateway_addr = match &arguments.gateway_address { + Some(address) => Some(Address::from_str(address)?), + None => None, + }; - log::info!("funded subnet: {:} at epoch: {epoch:}", arguments.subnet); + println!( + "fund performed in epoch: {:?}", + provider + .fund( + subnet, + gateway_addr, + from, + to, + f64_to_token_amount(arguments.amount)?, + ) + .await?, + ); Ok(()) } @@ -40,8 +58,8 @@ impl CommandLineHandler for Fund { #[derive(Debug, Args)] #[command(about = "Send funds from a parent to a child subnet")] pub(crate) struct FundArgs { - #[arg(long, short, help = "The JSON RPC server url for ipc agent")] - pub ipc_agent_url: Option, + #[arg(long, short, help = "The gateway address of the subnet")] + pub gateway_address: Option, #[arg(long, short, help = "The address to send funds from")] pub from: Option, #[arg( diff --git a/ipc/cli/src/commands/crossmsg/propagate.rs b/ipc/cli/src/commands/crossmsg/propagate.rs index b4da4ee8..4cfd0fda 100644 --- a/ipc/cli/src/commands/crossmsg/propagate.rs +++ b/ipc/cli/src/commands/crossmsg/propagate.rs @@ -3,15 +3,10 @@ //! Propagate cli command handler. use async_trait::async_trait; -use base64::Engine; use clap::Args; use std::fmt::Debug; -use crate::commands::get_ipc_agent_url; -use crate::config::json_rpc_methods; -use crate::server::propagate::PropagateParams; use crate::{CommandLineHandler, GlobalArguments}; -use ipc_provider::jsonrpc::{JsonRpcClient, JsonRpcClientImpl}; /// The command to propagate a message in the postbox. pub(crate) struct Propagate; @@ -20,26 +15,8 @@ pub(crate) struct Propagate; impl CommandLineHandler for Propagate { type Arguments = PropagateArgs; - async fn handle(global: &GlobalArguments, arguments: &Self::Arguments) -> anyhow::Result<()> { - log::debug!("propagate operation with args: {:?}", arguments); - - let url = get_ipc_agent_url(&arguments.ipc_agent_url, global)?; - let json_rpc_client = JsonRpcClientImpl::new(url, None); - - let postbox_msg_key = - base64::engine::general_purpose::STANDARD.decode(&arguments.postbox_msg_key)?; - let params = PropagateParams { - subnet: arguments.subnet.clone(), - from: arguments.from.clone(), - postbox_msg_key, - }; - json_rpc_client - .request::<()>(json_rpc_methods::PROPAGATE, serde_json::to_value(params)?) - .await?; - - log::info!("propagated subnet: {:}", arguments.subnet); - - Ok(()) + async fn handle(_global: &GlobalArguments, _arguments: &Self::Arguments) -> anyhow::Result<()> { + todo!() } } diff --git a/ipc/cli/src/commands/crossmsg/release.rs b/ipc/cli/src/commands/crossmsg/release.rs index db093c97..54836c78 100644 --- a/ipc/cli/src/commands/crossmsg/release.rs +++ b/ipc/cli/src/commands/crossmsg/release.rs @@ -4,11 +4,14 @@ use async_trait::async_trait; use clap::Args; -use std::fmt::Debug; +use fvm_shared::address::Address; +use ipc_sdk::subnet_id::SubnetID; +use std::{fmt::Debug, str::FromStr}; -use crate::commands::get_ipc_agent_url; -use crate::sdk::IpcAgentClient; -use crate::{CommandLineHandler, GlobalArguments}; +use crate::{ + f64_to_token_amount, get_ipc_provider, require_fil_addr_from_str, CommandLineHandler, + GlobalArguments, +}; /// The command to release funds from a child to a parent pub(crate) struct Release; @@ -20,18 +23,33 @@ impl CommandLineHandler for Release { async fn handle(global: &GlobalArguments, arguments: &Self::Arguments) -> anyhow::Result<()> { log::debug!("release operation with args: {:?}", arguments); - let url = get_ipc_agent_url(&arguments.ipc_agent_url, global)?; - let client = IpcAgentClient::default_from_url(url); - let epoch = client - .release( - &arguments.subnet, - arguments.from.clone(), - arguments.to.clone(), - arguments.amount, - ) - .await?; + let mut provider = get_ipc_provider(global)?; + let subnet = SubnetID::from_str(&arguments.subnet)?; + let from = match &arguments.from { + Some(address) => Some(Address::from_str(address)?), + None => None, + }; + let to = match &arguments.to { + Some(address) => Some(require_fil_addr_from_str(address)?), + None => None, + }; + let gateway_addr = match &arguments.gateway_address { + Some(address) => Some(require_fil_addr_from_str(address)?), + None => None, + }; - log::info!("released subnet: {:} at epoch {epoch:}", arguments.subnet); + println!( + "release performed in epoch: {:?}", + provider + .release( + subnet, + gateway_addr, + from, + to, + f64_to_token_amount(arguments.amount)?, + ) + .await?, + ); Ok(()) } @@ -40,8 +58,8 @@ impl CommandLineHandler for Release { #[derive(Debug, Args)] #[command(about = "Release operation in the gateway actor")] pub(crate) struct ReleaseArgs { - #[arg(long, short, help = "The JSON RPC server url for ipc agent")] - pub ipc_agent_url: Option, + #[arg(long, short, help = "The gateway address of the subnet")] + pub gateway_address: Option, #[arg(long, short, help = "The address that releases funds")] pub from: Option, #[arg( diff --git a/ipc/cli/src/commands/mod.rs b/ipc/cli/src/commands/mod.rs index 99286501..912df22a 100644 --- a/ipc/cli/src/commands/mod.rs +++ b/ipc/cli/src/commands/mod.rs @@ -4,26 +4,27 @@ // mod checkpoint; mod config; -// mod crossmsg; +mod crossmsg; // mod daemon; mod subnet; mod util; mod wallet; // use crate::commands::checkpoint::CheckpointCommandsArgs; -// use crate::commands::crossmsg::CrossMsgsCommandsArgs; +use crate::commands::crossmsg::CrossMsgsCommandsArgs; // use crate::commands::daemon::{LaunchDaemon, LaunchDaemonArgs}; use crate::commands::util::UtilCommandsArgs; -// use crate::server::{new_evm_keystore_from_path, new_keystore_from_path}; use crate::GlobalArguments; use anyhow::{Context, Result}; use clap::{Command, CommandFactory, Parser, Subcommand}; use clap_complete::{generate, Generator, Shell}; use fvm_shared::econ::TokenAmount; +use ipc_provider::manager::evm::ethers_address_to_fil_address; use std::fmt::Debug; use std::io; +use std::str::FromStr; use crate::commands::config::ConfigCommandsArgs; use crate::commands::wallet::WalletCommandsArgs; @@ -42,7 +43,7 @@ enum Commands { Config(ConfigCommandsArgs), Subnet(SubnetCommandsArgs), Wallet(WalletCommandsArgs), - // CrossMsg(CrossMsgsCommandsArgs), + CrossMsg(CrossMsgsCommandsArgs), // Checkpoint(CheckpointCommandsArgs), Util(UtilCommandsArgs), } @@ -107,7 +108,7 @@ pub async fn cli() -> anyhow::Result<()> { // Commands::Daemon(args) => LaunchDaemon::handle(global, args).await, Commands::Config(args) => args.handle(global).await, Commands::Subnet(args) => args.handle(global).await, - // Commands::CrossMsg(args) => args.handle(global).await, + Commands::CrossMsg(args) => args.handle(global).await, Commands::Wallet(args) => args.handle(global).await, // Commands::Checkpoint(args) => args.handle(global).await, Commands::Util(args) => args.handle(global).await, @@ -134,12 +135,19 @@ pub(crate) fn f64_to_token_amount(f: f64) -> anyhow::Result { Ok(TokenAmount::from_nano(nano as u128)) } -// pub(crate) fn get_evm_keystore(path: &Option) -> Result> { -// match path { -// Some(p) => new_evm_keystore_from_path(p), -// None => new_evm_keystore_from_path(&default_repo_path()), -// } -// } +/// Receives a f/eth-address as an input and returns the corresponding +/// filecoin or delegated address, respectively +pub(crate) fn require_fil_addr_from_str(s: &str) -> anyhow::Result { + let addr = match fvm_shared::address::Address::from_str(s) { + Err(_) => { + // see if it is an eth address + let addr = ethers::types::Address::from_str(s)?; + ethers_address_to_fil_address(&addr)? + } + Ok(addr) => addr, + }; + Ok(addr) +} #[cfg(test)] mod tests { diff --git a/ipc/cli/src/commands/subnet/list_subnets.rs b/ipc/cli/src/commands/subnet/list_subnets.rs index f0b1a75d..ce23b557 100644 --- a/ipc/cli/src/commands/subnet/list_subnets.rs +++ b/ipc/cli/src/commands/subnet/list_subnets.rs @@ -4,12 +4,12 @@ use async_trait::async_trait; use clap::Args; -use fvm_shared::{address::Address, econ::TokenAmount}; +use fvm_shared::econ::TokenAmount; use ipc_sdk::subnet_id::SubnetID; use std::fmt::Debug; use std::str::FromStr; -use crate::{get_ipc_provider, CommandLineHandler, GlobalArguments}; +use crate::{get_ipc_provider, require_fil_addr_from_str, CommandLineHandler, GlobalArguments}; /// The command to create a new subnet actor. pub(crate) struct ListSubnets; @@ -25,7 +25,7 @@ impl CommandLineHandler for ListSubnets { let subnet = SubnetID::from_str(&arguments.subnet)?; let gateway_addr = match &arguments.gateway_address { - Some(address) => Some(Address::from_str(address)?), + Some(address) => Some(require_fil_addr_from_str(address)?), None => None, }; diff --git a/ipc/cli/src/commands/subnet/list_validators.rs b/ipc/cli/src/commands/subnet/list_validators.rs index e32e3d21..b0bf8138 100644 --- a/ipc/cli/src/commands/subnet/list_validators.rs +++ b/ipc/cli/src/commands/subnet/list_validators.rs @@ -4,11 +4,10 @@ use async_trait::async_trait; use clap::Args; -use fvm_shared::address::Address; use ipc_sdk::subnet_id::SubnetID; use std::{fmt::Debug, str::FromStr}; -use crate::{get_ipc_provider, CommandLineHandler, GlobalArguments}; +use crate::{get_ipc_provider, require_fil_addr_from_str, CommandLineHandler, GlobalArguments}; /// The command to create a new subnet actor. pub(crate) struct ListValidators; @@ -24,7 +23,7 @@ impl CommandLineHandler for ListValidators { let subnet = SubnetID::from_str(&arguments.subnet)?; let gateway_addr = match &arguments.gateway_address { - Some(address) => Some(Address::from_str(address)?), + Some(address) => Some(require_fil_addr_from_str(address)?), None => None, }; diff --git a/ipc/cli/src/commands/subnet/send_value.rs b/ipc/cli/src/commands/subnet/send_value.rs index 8f96d48d..fa0869b1 100644 --- a/ipc/cli/src/commands/subnet/send_value.rs +++ b/ipc/cli/src/commands/subnet/send_value.rs @@ -5,11 +5,13 @@ use async_trait::async_trait; use clap::Args; use fvm_shared::address::Address; -use ipc_provider::manager::evm::ethers_address_to_fil_address; use ipc_sdk::subnet_id::SubnetID; use std::{fmt::Debug, str::FromStr}; -use crate::{f64_to_token_amount, get_ipc_provider, CommandLineHandler, GlobalArguments}; +use crate::{ + f64_to_token_amount, get_ipc_provider, require_fil_addr_from_str, CommandLineHandler, + GlobalArguments, +}; pub(crate) struct SendValue; @@ -27,20 +29,13 @@ impl CommandLineHandler for SendValue { None => None, }; - // try to get the `to` as an FVM address and an Eth - // address. We should include a wrapper type to make - // this easier through the whole code base. - let to = match Address::from_str(&arguments.to) { - Err(_) => { - // see if it is an eth address - let addr = ethers::types::Address::from_str(&arguments.to)?; - ethers_address_to_fil_address(&addr)? - } - Ok(addr) => addr, - }; - provider - .send_value(&subnet, from, to, f64_to_token_amount(arguments.amount)?) + .send_value( + &subnet, + from, + require_fil_addr_from_str(&arguments.to)?, + f64_to_token_amount(arguments.amount)?, + ) .await } } diff --git a/ipc/provider/src/lib.rs b/ipc/provider/src/lib.rs index 90a41601..e1bc316f 100644 --- a/ipc/provider/src/lib.rs +++ b/ipc/provider/src/lib.rs @@ -348,12 +348,14 @@ impl IpcProvider { conn.manager().list_child_subnets(gateway_addr).await } + /// Funds an account in a child subnet, if `to` is `None`, the self account + /// is funded. pub async fn fund( &mut self, subnet: SubnetID, gateway_addr: Option
, from: Option
, - to: Address, + to: Option
, amount: TokenAmount, ) -> anyhow::Result { let parent = subnet.parent().ok_or_else(|| anyhow!("no parent found"))?; @@ -372,16 +374,18 @@ impl IpcProvider { }; conn.manager() - .fund(subnet, gateway_addr, sender, to, amount) + .fund(subnet, gateway_addr, sender, to.unwrap_or(sender), amount) .await } + /// Release to an account in a child subnet, if `to` is `None`, the self account + /// is funded. pub async fn release( &mut self, subnet: SubnetID, gateway_addr: Option
, from: Option
, - to: Address, + to: Option
, amount: TokenAmount, ) -> anyhow::Result { let conn = match self.connection(&subnet) { @@ -399,7 +403,7 @@ impl IpcProvider { }; conn.manager() - .release(subnet, gateway_addr, sender, to, amount) + .release(subnet, gateway_addr, sender, to.unwrap_or(sender), amount) .await } From b7c701df418f33ac0a3514abfd449b43193c42a7 Mon Sep 17 00:00:00 2001 From: Alfonso de la Rocha Date: Fri, 8 Sep 2023 17:58:05 +0200 Subject: [PATCH 3/4] ipc-299: implement checkpoint cli commands --- .../commands/checkpoint/list_checkpoints.rs | 25 ++--------------- .../commands/checkpoint/topdown_executed.rs | 28 ++++++++++++------- ipc/cli/src/commands/mod.rs | 8 +++--- 3 files changed, 24 insertions(+), 37 deletions(-) diff --git a/ipc/cli/src/commands/checkpoint/list_checkpoints.rs b/ipc/cli/src/commands/checkpoint/list_checkpoints.rs index bf3eaca9..3ea5c95d 100644 --- a/ipc/cli/src/commands/checkpoint/list_checkpoints.rs +++ b/ipc/cli/src/commands/checkpoint/list_checkpoints.rs @@ -8,8 +8,6 @@ use async_trait::async_trait; use clap::Args; use fvm_shared::clock::ChainEpoch; -use crate::commands::get_ipc_agent_url; -use crate::sdk::IpcAgentClient; use crate::{CommandLineHandler, GlobalArguments}; /// The command to list checkpoints committed in a subnet actor. @@ -19,34 +17,15 @@ pub(crate) struct ListBottomUpCheckpoints; impl CommandLineHandler for ListBottomUpCheckpoints { type Arguments = ListBottomUpCheckpointsArgs; - async fn handle(global: &GlobalArguments, arguments: &Self::Arguments) -> anyhow::Result<()> { + async fn handle(_global: &GlobalArguments, arguments: &Self::Arguments) -> anyhow::Result<()> { log::debug!("list checkpoints with args: {:?}", arguments); - - let url = get_ipc_agent_url(&arguments.ipc_agent_url, global)?; - let client = IpcAgentClient::default_from_url(url); - let checkpoints = client - .list_bottom_up_checkpoints(&arguments.subnet, arguments.from_epoch, arguments.to_epoch) - .await?; - - for c in checkpoints.iter() { - log::info!( - "epoch {} - prev_check={}, cross_msgs={}, child_checks={}", - c["epoch"], - c["prev_check"], - c["cross_msgs"], - c["children"] - ); - } - - Ok(()) + todo!() } } #[derive(Debug, Args)] #[command(about = "List bottom-up checkpoints")] pub(crate) struct ListBottomUpCheckpointsArgs { - #[arg(long, short, help = "The JSON RPC server url for ipc agent")] - pub ipc_agent_url: Option, #[arg(long, short, help = "The subnet id of the checkpointing subnet")] pub subnet: String, #[arg(long, short, help = "Include checkpoints from this epoch")] diff --git a/ipc/cli/src/commands/checkpoint/topdown_executed.rs b/ipc/cli/src/commands/checkpoint/topdown_executed.rs index 1d395f53..503275ea 100644 --- a/ipc/cli/src/commands/checkpoint/topdown_executed.rs +++ b/ipc/cli/src/commands/checkpoint/topdown_executed.rs @@ -2,14 +2,13 @@ // SPDX-License-Identifier: MIT //! Last top-down checkpoint executed in subnet -use std::fmt::Debug; +use std::{fmt::Debug, str::FromStr}; use async_trait::async_trait; use clap::Args; +use ipc_sdk::subnet_id::SubnetID; -use crate::commands::get_ipc_agent_url; -use crate::sdk::IpcAgentClient; -use crate::{CommandLineHandler, GlobalArguments}; +use crate::{get_ipc_provider, require_fil_addr_from_str, CommandLineHandler, GlobalArguments}; /// The command to get the latest epoch executed for a top-down checkpoint pub(crate) struct LastTopDownExec; @@ -21,11 +20,20 @@ impl CommandLineHandler for LastTopDownExec { async fn handle(global: &GlobalArguments, arguments: &Self::Arguments) -> anyhow::Result<()> { log::debug!("last topdown exec with args: {:?}", arguments); - let url = get_ipc_agent_url(&arguments.ipc_agent_url, global)?; - let client = IpcAgentClient::default_from_url(url); - let epoch = client.last_top_down_executed(&arguments.subnet).await?; + let provider = get_ipc_provider(global)?; + let subnet = SubnetID::from_str(&arguments.subnet)?; - log::info!("Last top-down checkpoint executed in epoch: {epoch:}"); + let gateway_addr = match &arguments.gateway_address { + Some(address) => Some(require_fil_addr_from_str(address)?), + None => None, + }; + + println!( + "epoch: {:?}", + provider + .last_topdown_executed(&subnet, gateway_addr) + .await? + ); Ok(()) } @@ -34,8 +42,8 @@ impl CommandLineHandler for LastTopDownExec { #[derive(Debug, Args)] #[command(about = "Epoch of the last top-down checkpoint executed")] pub(crate) struct LastTopDownExecArgs { - #[arg(long, short, help = "The JSON RPC server url for ipc agent")] - pub ipc_agent_url: Option, + #[arg(long, short, help = "The gateway address to query subnets")] + pub gateway_address: Option, #[arg(long, short, help = "The subnet id of the checkpointing subnet")] pub subnet: String, } diff --git a/ipc/cli/src/commands/mod.rs b/ipc/cli/src/commands/mod.rs index 912df22a..8861f01f 100644 --- a/ipc/cli/src/commands/mod.rs +++ b/ipc/cli/src/commands/mod.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: MIT //! This mod contains the different command line implementations. -// mod checkpoint; +mod checkpoint; mod config; mod crossmsg; // mod daemon; @@ -10,7 +10,7 @@ mod subnet; mod util; mod wallet; -// use crate::commands::checkpoint::CheckpointCommandsArgs; +use crate::commands::checkpoint::CheckpointCommandsArgs; use crate::commands::crossmsg::CrossMsgsCommandsArgs; // use crate::commands::daemon::{LaunchDaemon, LaunchDaemonArgs}; use crate::commands::util::UtilCommandsArgs; @@ -44,7 +44,7 @@ enum Commands { Subnet(SubnetCommandsArgs), Wallet(WalletCommandsArgs), CrossMsg(CrossMsgsCommandsArgs), - // Checkpoint(CheckpointCommandsArgs), + Checkpoint(CheckpointCommandsArgs), Util(UtilCommandsArgs), } @@ -110,7 +110,7 @@ pub async fn cli() -> anyhow::Result<()> { Commands::Subnet(args) => args.handle(global).await, Commands::CrossMsg(args) => args.handle(global).await, Commands::Wallet(args) => args.handle(global).await, - // Commands::Checkpoint(args) => args.handle(global).await, + Commands::Checkpoint(args) => args.handle(global).await, Commands::Util(args) => args.handle(global).await, }; From 0182ee657958c1ead6c7dcf4dfd7ef1ba1e2a3d7 Mon Sep 17 00:00:00 2001 From: Alfonso de la Rocha Date: Wed, 13 Sep 2023 05:43:02 +0200 Subject: [PATCH 4/4] ipc-299: implement get-chain-id --- ipc/cli/src/commands/subnet/rpc.rs | 2 +- ipc/provider/src/lib.rs | 12 ++++++++++++ ipc/provider/src/manager/evm/manager.rs | 9 +++++++++ ipc/provider/src/manager/fevm.rs | 4 ++++ ipc/provider/src/manager/fvm/mod.rs | 4 ++++ ipc/provider/src/manager/subnet.rs | 5 +++++ 6 files changed, 35 insertions(+), 1 deletion(-) diff --git a/ipc/cli/src/commands/subnet/rpc.rs b/ipc/cli/src/commands/subnet/rpc.rs index 9d41f519..b6bbc25f 100644 --- a/ipc/cli/src/commands/subnet/rpc.rs +++ b/ipc/cli/src/commands/subnet/rpc.rs @@ -28,7 +28,7 @@ impl CommandLineHandler for RPCSubnet { }; println!("rpc: {:?}", conn.subnet().rpc_http().to_string()); - println!("chainID: {:?}", subnet.chain_id()); + println!("chainID: {:?}", conn.manager().get_chain_id().await?); Ok(()) } } diff --git a/ipc/provider/src/lib.rs b/ipc/provider/src/lib.rs index e1bc316f..7b0730a9 100644 --- a/ipc/provider/src/lib.rs +++ b/ipc/provider/src/lib.rs @@ -625,6 +625,18 @@ impl IpcProvider { conn.manager().get_block_hash(height).await } + + pub async fn get_chain_id(&self, subnet: &SubnetID) -> anyhow::Result { + let conn = match self.connection(subnet) { + None => return Err(anyhow!("target subnet not found")), + Some(conn) => conn, + }; + + let subnet_config = conn.subnet(); + self.check_subnet(subnet_config)?; + + conn.manager().get_chain_id().await + } } /// Lotus JSON keytype format diff --git a/ipc/provider/src/manager/evm/manager.rs b/ipc/provider/src/manager/evm/manager.rs index 44df6cf9..017990dd 100644 --- a/ipc/provider/src/manager/evm/manager.rs +++ b/ipc/provider/src/manager/evm/manager.rs @@ -587,6 +587,15 @@ impl SubnetManager for EthSubnetManager { genesis_epoch, }) } + + async fn get_chain_id(&self) -> Result { + Ok(self + .ipc_contract_info + .provider + .get_chainid() + .await? + .to_string()) + } } #[async_trait] diff --git a/ipc/provider/src/manager/fevm.rs b/ipc/provider/src/manager/fevm.rs index 31c34591..159cfbf2 100644 --- a/ipc/provider/src/manager/fevm.rs +++ b/ipc/provider/src/manager/fevm.rs @@ -230,6 +230,10 @@ impl SubnetManager for FevmSubnetManager { .get_validator_set(subnet_id, gateway, epoch) .await } + + async fn get_chain_id(&self) -> anyhow::Result { + self.evm_subnet_manager.get_chain_id().await + } } #[async_trait] diff --git a/ipc/provider/src/manager/fvm/mod.rs b/ipc/provider/src/manager/fvm/mod.rs index bfc12c3a..9ac87d1d 100644 --- a/ipc/provider/src/manager/fvm/mod.rs +++ b/ipc/provider/src/manager/fvm/mod.rs @@ -395,6 +395,10 @@ impl SubnetManager for LotusSubnetManager { genesis_epoch, }) } + + async fn get_chain_id(&self) -> Result { + unimplemented!() + } } impl LotusSubnetManager { diff --git a/ipc/provider/src/manager/subnet.rs b/ipc/provider/src/manager/subnet.rs index c5c2162d..ac463636 100644 --- a/ipc/provider/src/manager/subnet.rs +++ b/ipc/provider/src/manager/subnet.rs @@ -129,6 +129,11 @@ pub trait SubnetManager: Send + Sync + TopDownCheckpointQuery { gateway: Option
, epoch: Option, ) -> Result; + + /// Get chainID for the network. + /// Returning as a `String` because the maximum value for an EVM + /// networks is a `U256` that wouldn't fit in an integer type. + async fn get_chain_id(&self) -> Result; } /// Trait to interact with a subnet to query the necessary information for top down checkpoint.