Skip to content

Commit

Permalink
feat(cli): forest-cli f3 certs get (#4953)
Browse files Browse the repository at this point in the history
  • Loading branch information
hanabi1224 authored Oct 31, 2024
1 parent 9bebafd commit d2362b4
Show file tree
Hide file tree
Showing 7 changed files with 490 additions and 9 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
- [#4949](https://github.com/ChainSafe/forest/pull/4949) Added
`forest-cli f3 status` CLI command.

- [#4949](https://github.com/ChainSafe/forest/pull/4949) Added
`forest-cli f3 certs get` CLI command.

- [#4706](https://github.com/ChainSafe/forest/issues/4706) Add support for the
`Filecoin.EthSendRawTransaction` RPC method.

Expand Down
5 changes: 5 additions & 0 deletions src/blocks/tipset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ impl TipsetKey {
pub fn iter(&self) -> impl Iterator<Item = Cid> + '_ {
self.0.iter()
}

/// Returns the number of `CID`s
pub fn len(&self) -> usize {
self.0.len()
}
}

impl From<NonEmpty<Cid>> for TipsetKey {
Expand Down
5 changes: 5 additions & 0 deletions src/cid_collections/small_cid_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ impl SmallCidNonEmptyVec {
pub fn iter(&self) -> impl Iterator<Item = Cid> + '_ {
self.0.iter().map(|cid| Cid::from(cid.clone()))
}

/// Returns the number of `CID`s
pub fn len(&self) -> usize {
self.0.len()
}
}

impl<'a> IntoIterator for &'a SmallCidNonEmptyVec {
Expand Down
214 changes: 212 additions & 2 deletions src/cli/subcommands/f3_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

use crate::rpc::{
self,
f3::{F3Instant, F3Manifest},
f3::{F3Instant, F3Manifest, FinalityCertificate},
prelude::*,
};
use cid::Cid;
Expand Down Expand Up @@ -33,6 +33,9 @@ pub enum F3Commands {
},
/// Checks the F3 status.
Status,
/// Manages interactions with F3 finality certificates.
#[command(subcommand, visible_alias = "c")]
Certs(F3CertsCommands),
}

impl F3Commands {
Expand Down Expand Up @@ -62,6 +65,43 @@ impl F3Commands {
println!("{}", manifest_template.render_once()?);
Ok(())
}
Self::Certs(cmd) => cmd.run(client).await,
}
}
}

/// Manages interactions with F3 finality certificates.
#[derive(Debug, Subcommand)]
pub enum F3CertsCommands {
/// Gets an F3 finality certificate to a given instance ID, or the latest certificate if no instance is specified.
Get {
instance: Option<u64>,
/// The output format.
#[arg(long, value_enum, default_value_t = F3OutputFormat::Text)]
output: F3OutputFormat,
},
}

impl F3CertsCommands {
pub async fn run(self, client: rpc::Client) -> anyhow::Result<()> {
match self {
Self::Get { instance, output } => {
let cert = if let Some(instance) = instance {
client.call(F3GetCertificate::request((instance,))?).await?
} else {
client.call(F3GetLatestCertificate::request(())?).await?
};
match output {
F3OutputFormat::Text => {
let template = FinalityCertificateTemplate::new(cert);
println!("{}", template.render_once()?);
}
F3OutputFormat::Json => {
println!("{}", serde_json::to_string_pretty(&cert)?);
}
}
Ok(())
}
}
}
}
Expand Down Expand Up @@ -95,6 +135,18 @@ impl ProgressTemplate {
}
}

#[derive(TemplateSimple, Debug, Clone, Serialize, Deserialize)]
#[template(path = "cli/f3/certificate.stpl")]
struct FinalityCertificateTemplate {
cert: FinalityCertificate,
}

impl FinalityCertificateTemplate {
fn new(cert: FinalityCertificate) -> Self {
Self { cert }
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -148,8 +200,166 @@ mod tests {
"MaximumPollInterval": 120000000000_u64
}
});
let manifest: F3Manifest = serde_json::from_value(lotus_json.clone()).unwrap();
let manifest: F3Manifest = serde_json::from_value(lotus_json).unwrap();
let template = ManifestTemplate::new(manifest);
println!("{}", template.render_once().unwrap());
}

#[test]
fn test_progress_template() {
let lotus_json = serde_json::json!({
"ID": 1000,
"Round": 0,
"Phase": 0
});
let progress: F3Instant = serde_json::from_value(lotus_json).unwrap();
let template = ProgressTemplate::new(progress);
println!("{}", template.render_once().unwrap());
}

#[test]
fn test_finality_certificate_template() {
// lotus f3 c get --output json 6204
let lotus_json = serde_json::json!({
"GPBFTInstance": 6204,
"ECChain": [
{
"Epoch": 2088927,
"Key": "AXGg5AIg1NBjOnFimwUueRXQQzvPbHZO6vXbvqNA1gcomlVrq5MBcaDkAiCaOt71j85kjjq3SZF0NQq03tauEW3iwscIr4Qw0wna+g==",
"PowerTable": {
"/": "bafy2bzaceazjn2promafvtkaquebfgc3xvhoavdbxwns4i54ilgnzch7pkgua"
},
"Commitments": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
},
{
"Epoch": 2088928,
"Key": "AXGg5AIgFn9g3q/ATrgWiWzUYZLrtN/POrkNWFPmUShj/MDqZ5IBcaDkAiACwpEW4PvUCOIsZRaYhF6W+L1bgGd2TUFLOkATNxvuGgFxoOQCILlKPpFgMxXYFcq2HslyxzBN9ZZ6iPrPSBI2uwT4tUAvAXGg5AIgwYDZ217HUZ6nGnm6fnNd5lhep2C02mSYkkjJPf5pOig=",
"PowerTable": {
"/": "bafy2bzaceazjn2promafvtkaquebfgc3xvhoavdbxwns4i54ilgnzch7pkgua"
},
"Commitments": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
]
}
],
"SupplementalData": {
"Commitments": [
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0
],
"PowerTable": {
"/": "bafy2bzaceazjn2promafvtkaquebfgc3xvhoavdbxwns4i54ilgnzch7pkgua"
}
},
"Signers": [
0,
3
],
"Signature": "uYtvw/NWm2jKQj+d99UAG4aiPnpAMSrwAWIusv0XkjsOYYR0fyU4nUM++cAQGO47E2/J8WSDjstLgL+yMVAFC+Tgao4o9ILXIlhqhxObnNZ/Ehanajthif9SaRe1AO69",
"PowerTableDelta": [
{
"ParticipantID": 3782,
"PowerDelta": "76347338653696",
"SigningKey": "lXSMTNEVmIdVxJV4clmW35jrlsBEfytNUGTWVih2dFlQ1k/7QQttsUGzpD5JoNaQ"
}
]
});
let cert: FinalityCertificate = serde_json::from_value(lotus_json).unwrap();
let template = FinalityCertificateTemplate::new(cert);
println!("{}", template.render_once().unwrap());
}
}
6 changes: 3 additions & 3 deletions src/rpc/methods/f3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
mod types;
mod util;

pub use self::types::{F3Instant, F3LeaseManager, F3Manifest};
pub use self::types::{F3Instant, F3LeaseManager, F3Manifest, FinalityCertificate};
use self::{types::*, util::*};
use super::wallet::WalletSign;
use crate::{
Expand Down Expand Up @@ -566,7 +566,7 @@ impl RpcMethod<1> for F3GetCertificate {
const PERMISSION: Permission = Permission::Read;

type Params = (u64,);
type Ok = serde_json::Value;
type Ok = FinalityCertificate;

async fn handle(
_: Ctx<impl Blockstore>,
Expand All @@ -589,7 +589,7 @@ impl RpcMethod<0> for F3GetLatestCertificate {
const PERMISSION: Permission = Permission::Read;

type Params = ();
type Ok = serde_json::Value;
type Ok = FinalityCertificate;

async fn handle(_: Ctx<impl Blockstore>, _: Self::Params) -> Result<Self::Ok, ServerError> {
let client = get_rpc_http_client()?;
Expand Down
Loading

0 comments on commit d2362b4

Please sign in to comment.