Skip to content

Commit

Permalink
feat: add format flag in chain head command (#5215)
Browse files Browse the repository at this point in the history
  • Loading branch information
akaladarshi authored Feb 3, 2025
1 parent 6fd344b commit 2755a80
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 17 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
- [#4851](https://github.com/ChainSafe/forest/issues/4851) Add support for `FOREST_MAX_FILTER_RESULTS` in `Filecoin.EthGetLogs` RPC method.
Add an `[events]` section to Forest configuration file.

- [#4954](https://github.com/ChainSafe/forest/issues/4954) Add `--format json` to `forest-cli chain head` command.

### Changed

### Removed
Expand Down
1 change: 1 addition & 0 deletions scripts/tests/calibnet_other_check.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ $FOREST_CLI_PATH chain set-head --epoch -10 --force
echo "Test subcommand: chain head"
$FOREST_CLI_PATH chain head
$FOREST_CLI_PATH chain head --tipsets 10
$FOREST_CLI_PATH chain head --tipsets 5 --format json | jq 'length == 5'

echo "Test subcommand: info show"
$FOREST_CLI_PATH info show
Expand Down
51 changes: 44 additions & 7 deletions src/cli/subcommands/chain_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,13 @@ use cid::Cid;
use clap::Subcommand;
use nunny::Vec as NonEmpty;

use super::{print_pretty_lotus_json, print_rpc_res_cids};
use super::print_pretty_lotus_json;

#[derive(Debug, Clone, clap::ValueEnum)]
pub enum Format {
Json,
Text,
}

#[derive(Debug, Subcommand)]
pub enum ChainCommands {
Expand All @@ -29,6 +35,9 @@ pub enum ChainCommands {
/// Tipsets are categorized by epoch in descending order.
#[arg(short = 'n', long, default_value = "1")]
tipsets: u64,
/// Format of the output. `json` or `text`.
#[arg(long, default_value = "text")]
format: Format,
},

/// Reads and prints out a message referenced by the specified CID from the
Expand Down Expand Up @@ -68,7 +77,7 @@ impl ChainCommands {
print_pretty_lotus_json(ChainGetBlock::call(&client, (cid,)).await?)
}
Self::Genesis => print_pretty_lotus_json(ChainGetGenesis::call(&client, ()).await?),
Self::Head { tipsets } => print_chain_head(&client, tipsets).await,
Self::Head { tipsets, format } => print_chain_head(&client, tipsets, format).await,
Self::Message { cid } => {
let bytes = ChainReadObj::call(&client, (cid,)).await?;
match fvm_ipld_encoding::from_slice::<ChainMessage>(&bytes)? {
Expand Down Expand Up @@ -151,15 +160,43 @@ fn maybe_confirm(no_confirm: bool, prompt: impl Into<String>) -> anyhow::Result<
}
}

/// Print the first `n` tipsets from the head (inclusive).
async fn print_chain_head(client: &rpc::Client, n: u64) -> anyhow::Result<()> {
#[derive(Debug, serde::Serialize)]
struct TipsetInfo {
epoch: u64,
cids: Vec<String>,
}

/// Collects `n` tipsets from the head (inclusive) and returns them as a list of
/// [`TipsetInfo`] objects.
async fn collect_n_tipsets(client: &rpc::Client, n: u64) -> anyhow::Result<Vec<TipsetInfo>> {
ensure!(n > 0, "number of tipsets must be positive");
let current_epoch = ChainHead::call(client, ()).await?.epoch() as u64;

let mut tipsets = Vec::with_capacity(n as usize);
for epoch in (current_epoch.saturating_sub(n - 1)..=current_epoch).rev() {
let tipset = tipset_by_epoch_or_offset(client, epoch.try_into()?).await?;
println!("[{}]", epoch);
print_rpc_res_cids(tipset)?;
tipsets.push(TipsetInfo {
epoch,
cids: tipset.cids().iter().map(|cid| cid.to_string()).collect(),
});
}
Ok(tipsets)
}

/// Print the first `n` tipsets from the head (inclusive).
async fn print_chain_head(client: &rpc::Client, n: u64, format: Format) -> anyhow::Result<()> {
let tipsets = collect_n_tipsets(client, n).await?;
match format {
Format::Json => {
println!("{}", serde_json::to_string_pretty(&tipsets)?);
}
Format::Text => {
tipsets.iter().for_each(|epoch_info| {
println!("[{}]", epoch_info.epoch);
epoch_info.cids.iter().for_each(|cid| {
println!("{}", cid);
});
});
}
}
Ok(())
}
11 changes: 1 addition & 10 deletions src/cli/subcommands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ use std::io::Write;

pub(crate) use crate::cli_shared::cli::Config;
use crate::cli_shared::cli::HELP_MESSAGE;
use crate::lotus_json::HasLotusJson;
use crate::utils::version::FOREST_VERSION_STRING;
use crate::{blocks::Tipset, lotus_json::HasLotusJson};
use clap::Parser;
use tracing::error;

Expand Down Expand Up @@ -124,15 +124,6 @@ pub(super) fn print_pretty_lotus_json<T: HasLotusJson>(obj: T) -> anyhow::Result
Ok(())
}

/// Prints a tipset from a HTTP JSON-RPC response result
pub(super) fn print_rpc_res_cids(tipset: Tipset) -> anyhow::Result<()> {
for cid in &tipset.cids() {
println!("{cid}");
}

Ok(())
}

/// Prints a bytes HTTP JSON-RPC response result
pub(super) fn print_rpc_res_bytes(obj: Vec<u8>) -> anyhow::Result<()> {
println!("{}", String::from_utf8(obj)?);
Expand Down

0 comments on commit 2755a80

Please sign in to comment.