Skip to main content

forest/rpc/methods/
common.rs

1// Copyright 2019-2026 ChainSafe Systems
2// SPDX-License-Identifier: Apache-2.0, MIT
3
4use crate::lotus_json::lotus_json_with_self;
5use crate::rpc::error::ServerError;
6use crate::rpc::{ApiPaths, Ctx, Permission, RpcMethod};
7use enumflags2::BitFlags;
8use schemars::JsonSchema;
9use serde::{Deserialize, Serialize};
10use std::sync::LazyLock;
11use uuid::Uuid;
12
13static SESSION_UUID: LazyLock<Uuid> = LazyLock::new(crate::utils::rand::new_uuid_v4);
14
15/// The returned session UUID uniquely identifies the API node.
16pub enum Session {}
17impl RpcMethod<0> for Session {
18    const NAME: &'static str = "Filecoin.Session";
19    const PARAM_NAMES: [&'static str; 0] = [];
20    const API_PATHS: BitFlags<ApiPaths> = ApiPaths::all();
21    const PERMISSION: Permission = Permission::Read;
22    const DESCRIPTION: &'static str =
23        "Returns a UUID that uniquely identifies this node for the current session.";
24
25    type Params = ();
26    type Ok = Uuid;
27
28    async fn handle(_: Ctx, (): Self::Params, _: &http::Extensions) -> Result<Uuid, ServerError> {
29        Ok(*SESSION_UUID)
30    }
31}
32
33pub enum Version {}
34impl RpcMethod<0> for Version {
35    const NAME: &'static str = "Filecoin.Version";
36    const PARAM_NAMES: [&'static str; 0] = [];
37    const API_PATHS: BitFlags<ApiPaths> = ApiPaths::all();
38    const PERMISSION: Permission = Permission::Read;
39    const DESCRIPTION: &'static str = "Returns the node version, API version, and block delay.";
40
41    type Params = ();
42    type Ok = PublicVersion;
43
44    async fn handle(
45        ctx: Ctx,
46        (): Self::Params,
47        _: &http::Extensions,
48    ) -> Result<Self::Ok, ServerError> {
49        Ok(PublicVersion {
50            version: crate::utils::version::FOREST_VERSION_STRING.clone(),
51            // This matches Lotus's versioning for the API v1.
52            // For the API v0, we don't support it but it should be `1.5.0`.
53            api_version: ShiftingVersion::new(2, 3, 0),
54            block_delay: ctx.chain_config().block_delay_secs,
55            agent: "forest".into(),
56        })
57    }
58}
59
60pub enum Shutdown {}
61impl RpcMethod<0> for Shutdown {
62    const NAME: &'static str = "Filecoin.Shutdown";
63    const PARAM_NAMES: [&'static str; 0] = [];
64    const API_PATHS: BitFlags<ApiPaths> = ApiPaths::all();
65    const PERMISSION: Permission = Permission::Admin;
66    const DESCRIPTION: &'static str = "Shuts the node down.";
67
68    type Params = ();
69    type Ok = ();
70
71    async fn handle(
72        ctx: Ctx,
73        (): Self::Params,
74        _: &http::Extensions,
75    ) -> Result<Self::Ok, ServerError> {
76        ctx.shutdown.send(()).await?;
77        Ok(())
78    }
79}
80
81pub enum StartTime {}
82impl RpcMethod<0> for StartTime {
83    const NAME: &'static str = "Filecoin.StartTime";
84    const PARAM_NAMES: [&'static str; 0] = [];
85    const API_PATHS: BitFlags<ApiPaths> = ApiPaths::all();
86    const PERMISSION: Permission = Permission::Read;
87    const DESCRIPTION: &'static str = "Returns the time at which the node was started.";
88
89    type Params = ();
90    type Ok = chrono::DateTime<chrono::Utc>;
91
92    async fn handle(
93        ctx: Ctx,
94        (): Self::Params,
95        _: &http::Extensions,
96    ) -> Result<Self::Ok, ServerError> {
97        Ok(ctx.start_time)
98    }
99}
100
101/// Represents the current version of the API.
102#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
103#[serde(rename_all = "PascalCase")]
104pub struct PublicVersion {
105    pub version: String,
106    #[serde(rename = "APIVersion")]
107    pub api_version: ShiftingVersion,
108    pub block_delay: u32,
109    // See <https://github.com/filecoin-project/lotus/blob/a0ecb8687f1c60d5e66040b6de364dbc9cc4d253/api/api_common.go#L78>
110    pub agent: String,
111}
112lotus_json_with_self!(PublicVersion);
113
114/// Integer based value on version information. Highest order bits for Major,
115/// Mid order for Minor and lowest for Patch.
116#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
117pub struct ShiftingVersion(u32);
118
119impl ShiftingVersion {
120    pub const fn new(major: u64, minor: u64, patch: u64) -> Self {
121        Self(((major as u32) << 16) | ((minor as u32) << 8) | (patch as u32))
122    }
123}