diff --git a/CHANGELOG.md b/CHANGELOG.md index ae5638103af..cfc80be53f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,9 @@ - [#4937](https://github.com/ChainSafe/forest/pull/4937) Added `forest-cli f3 manifest` CLI command. +- [#4949](https://github.com/ChainSafe/forest/pull/4949) Added + `forest-cli f3 status` CLI command. + - [#4706](https://github.com/ChainSafe/forest/issues/4706) Add support for the `Filecoin.EthSendRawTransaction` RPC method. diff --git a/src/cli/subcommands/f3_cmd.rs b/src/cli/subcommands/f3_cmd.rs index 4a73de7acf7..8335261959a 100644 --- a/src/cli/subcommands/f3_cmd.rs +++ b/src/cli/subcommands/f3_cmd.rs @@ -1,7 +1,11 @@ // Copyright 2019-2024 ChainSafe Systems // SPDX-License-Identifier: Apache-2.0, MIT -use crate::rpc::{self, f3::F3Manifest, prelude::*}; +use crate::rpc::{ + self, + f3::{F3Instant, F3Manifest}, + prelude::*, +}; use cid::Cid; use clap::{Subcommand, ValueEnum}; use sailfish::TemplateSimple; @@ -27,6 +31,8 @@ pub enum F3Commands { #[arg(long, value_enum, default_value_t = F3OutputFormat::Text)] output: F3OutputFormat, }, + /// Checks the F3 status. + Status, } impl F3Commands { @@ -45,6 +51,17 @@ impl F3Commands { } Ok(()) } + Self::Status => { + let is_running = client.call(F3IsRunning::request(())?).await?; + println!("Running: {is_running}"); + let progress = client.call(F3GetProgress::request(())?).await?; + let progress_template = ProgressTemplate::new(progress); + println!("{}", progress_template.render_once()?); + let manifest = client.call(F3GetManifest::request(())?).await?; + let manifest_template = ManifestTemplate::new(manifest); + println!("{}", manifest_template.render_once()?); + Ok(()) + } } } } @@ -66,6 +83,18 @@ impl ManifestTemplate { } } +#[derive(TemplateSimple, Debug, Clone, Serialize, Deserialize)] +#[template(path = "cli/f3/progress.stpl")] +struct ProgressTemplate { + progress: F3Instant, +} + +impl ProgressTemplate { + fn new(progress: F3Instant) -> Self { + Self { progress } + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/rpc/methods/f3.rs b/src/rpc/methods/f3.rs index 987ea136893..556d7a2086c 100644 --- a/src/rpc/methods/f3.rs +++ b/src/rpc/methods/f3.rs @@ -10,7 +10,7 @@ mod types; mod util; -pub use self::types::{F3LeaseManager, F3Manifest}; +pub use self::types::{F3Instant, F3LeaseManager, F3Manifest}; use self::{types::*, util::*}; use super::wallet::WalletSign; use crate::{ @@ -650,7 +650,7 @@ impl RpcMethod<0> for F3IsRunning { const PERMISSION: Permission = Permission::Read; type Params = (); - type Ok = serde_json::Value; + type Ok = bool; async fn handle(_: Ctx, (): Self::Params) -> Result { let client = get_rpc_http_client()?; diff --git a/src/rpc/methods/f3/types.rs b/src/rpc/methods/f3/types.rs index bc1f6ecb9d0..7d985ee24db 100644 --- a/src/rpc/methods/f3/types.rs +++ b/src/rpc/methods/f3/types.rs @@ -154,6 +154,21 @@ pub struct F3Instant { } lotus_json_with_self!(F3Instant); +impl F3Instant { + pub fn phase_string(&self) -> &'static str { + match self.phase { + 0 => "INITIAL", + 1 => "QUALITY", + 2 => "CONVERGE", + 3 => "PREPARE", + 4 => "COMMIT", + 5 => "DECIDE", + 6 => "TERMINATED", + _ => "UNKNOWN", + } + } +} + #[derive(PartialEq, Debug, Clone, Serialize, Deserialize, JsonSchema)] #[serde(rename_all = "PascalCase")] pub struct GpbftConfig { diff --git a/templates/cli/f3/progress.stpl b/templates/cli/f3/progress.stpl new file mode 100644 index 00000000000..2f97cf0ae88 --- /dev/null +++ b/templates/cli/f3/progress.stpl @@ -0,0 +1,4 @@ +Progress: + Instance: <%= progress.id %> + Round: <%= progress.round %> + Phase: <%= progress.phase_string() %>