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