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(long)]
39 force: bool,
40 #[arg(short, long)]
42 verbose: bool,
43 },
44 ReadState {
46 actor_address: StrictAddress,
48 },
49 ActorCids {
51 #[arg(long, default_value = "text")]
53 format: Format,
54 },
55}
56
57impl StateCommands {
58 pub async fn run(self, client: rpc::Client) -> anyhow::Result<()> {
59 match self {
60 Self::Fetch { root, save_to_file } => {
61 let ret = client
62 .call(
63 StateFetchRoot::request((root, save_to_file))?.with_timeout(Duration::MAX),
64 )
65 .await?;
66 println!("{ret}");
67 }
68 StateCommands::Compute {
69 epoch,
70 n_epochs,
71 force,
72 verbose,
73 } => {
74 let results = client
75 .call(
76 ForestStateCompute::request((epoch, n_epochs, Some(force)))?
77 .with_timeout(Duration::MAX),
78 )
79 .await?;
80 for ForestComputeStateOutput {
81 state_root,
82 epoch,
83 tipset_key,
84 } in results
85 {
86 if verbose {
87 println!("{state_root} (epoch: {epoch}, tipset key: {tipset_key})");
88 } else {
89 println!("{state_root}");
90 }
91 }
92 }
93 Self::ReadState { actor_address } => {
94 let tipset = ChainHead::call(&client, ()).await?;
95 let ret = client
96 .call(
97 StateReadState::request((actor_address.into(), tipset.key().into()))?
98 .with_timeout(Duration::MAX),
99 )
100 .await?;
101 println!("{}", ret.state.into_lotus_json_string_pretty()?);
102 }
103 Self::ActorCids { format } => {
104 let info = client.call(StateActorInfo::request(())?).await?;
105
106 match format {
107 Format::Json => {
108 println!("{}", serde_json::to_string_pretty(&info)?);
109 }
110 Format::Text => println!("{info}"),
111 }
112 }
113 }
114 Ok(())
115 }
116}