forest/cli/subcommands/
state_cmd.rs1use crate::lotus_json::HasLotusJson;
5use crate::rpc::state::{ForestComputeStateOutput, ForestStateCompute};
6use crate::rpc::{self, prelude::*};
7use crate::shim::address::StrictAddress;
8use crate::shim::clock::ChainEpoch;
9use cid::Cid;
10use clap::Subcommand;
11use std::num::NonZeroUsize;
12use std::path::PathBuf;
13use std::time::Duration;
14
15#[derive(Debug, Clone, clap::ValueEnum)]
16pub enum Format {
17 Json,
18 Text,
19}
20
21#[derive(Debug, Subcommand)]
22pub enum StateCommands {
23 Fetch {
24 root: Cid,
25 #[arg(short, long)]
27 save_to_file: Option<PathBuf>,
28 },
29 Compute {
31 #[arg(long)]
33 epoch: ChainEpoch,
34 #[arg(short, long)]
36 n_epochs: Option<NonZeroUsize>,
37 #[arg(short, long)]
39 verbose: bool,
40 },
41 ReadState {
43 actor_address: StrictAddress,
45 },
46 ActorCids {
48 #[arg(long, default_value = "text")]
50 format: Format,
51 },
52}
53
54impl StateCommands {
55 pub async fn run(self, client: rpc::Client) -> anyhow::Result<()> {
56 match self {
57 Self::Fetch { root, save_to_file } => {
58 let ret = client
59 .call(
60 StateFetchRoot::request((root, save_to_file))?.with_timeout(Duration::MAX),
61 )
62 .await?;
63 println!("{ret}");
64 }
65 StateCommands::Compute {
66 epoch,
67 n_epochs,
68 verbose,
69 } => {
70 let results = client
71 .call(
72 ForestStateCompute::request((epoch, n_epochs))?.with_timeout(Duration::MAX),
73 )
74 .await?;
75 for ForestComputeStateOutput {
76 state_root,
77 epoch,
78 tipset_key,
79 } in results
80 {
81 if verbose {
82 println!("{state_root} (epoch: {epoch}, tipset key: {tipset_key})");
83 } else {
84 println!("{state_root}");
85 }
86 }
87 }
88 Self::ReadState { actor_address } => {
89 let tipset = ChainHead::call(&client, ()).await?;
90 let ret = client
91 .call(
92 StateReadState::request((actor_address.into(), tipset.key().into()))?
93 .with_timeout(Duration::MAX),
94 )
95 .await?;
96 println!("{}", ret.state.into_lotus_json_string_pretty()?);
97 }
98 Self::ActorCids { format } => {
99 let info = client.call(StateActorInfo::request(())?).await?;
100
101 match format {
102 Format::Json => {
103 println!("{}", serde_json::to_string_pretty(&info)?);
104 }
105 Format::Text => println!("{info}"),
106 }
107 }
108 }
109 Ok(())
110 }
111}