Skip to content

Commit d13c21d

Browse files
authored
Cache process const strings (#6952)
1 parent 08044cf commit d13c21d

4 files changed

Lines changed: 55 additions & 12 deletions

File tree

src/lotus_json/arc.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,25 @@ impl<T: HasLotusJson + Clone> HasLotusJson for Arc<T> {
2323
Arc::new(T::from_lotus_json(lotus_json))
2424
}
2525
}
26+
27+
// `Arc<str>` can't reuse the blanket impl above (which requires `T: Sized`,
28+
// and `str` is not). `Arc<str>` already satisfies every `HasLotusJson`
29+
// consumer bound directly (`Serialize + DeserializeOwned + JsonSchema +
30+
// Clone + 'static`), so we make `LotusJson = Self` and keep the conversions
31+
// as identity — serializing the cached value takes no allocation.
32+
impl HasLotusJson for Arc<str> {
33+
type LotusJson = Self;
34+
35+
#[cfg(test)]
36+
fn snapshots() -> Vec<(serde_json::Value, Self)> {
37+
unimplemented!("tests are trivial for HasLotusJson<LotusJson = Self>")
38+
}
39+
40+
fn into_lotus_json(self) -> Self::LotusJson {
41+
self
42+
}
43+
44+
fn from_lotus_json(lotus_json: Self::LotusJson) -> Self {
45+
lotus_json
46+
}
47+
}

src/rpc/methods/eth.rs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ use serde::{Deserialize, Serialize};
7777
use std::num::NonZeroUsize;
7878
use std::ops::RangeInclusive;
7979
use std::str::FromStr;
80-
use std::sync::{Arc, LazyLock};
80+
use std::sync::{Arc, LazyLock, OnceLock};
8181
use utils::{decode_payload, lookup_eth_address};
8282

8383
static FOREST_TRACE_FILTER_MAX_RESULT: LazyLock<u64> =
@@ -764,17 +764,23 @@ impl RpcMethod<0> for Web3ClientVersion {
764764
const PERMISSION: Permission = Permission::Read;
765765

766766
type Params = ();
767-
type Ok = String;
767+
type Ok = Arc<str>;
768768

769769
async fn handle(
770770
_: Ctx<impl Blockstore + Send + Sync + 'static>,
771771
(): Self::Params,
772772
_: &http::Extensions,
773773
) -> Result<Self::Ok, ServerError> {
774-
Ok(format!(
775-
"forest/{}",
776-
*crate::utils::version::FOREST_VERSION_STRING
777-
))
774+
// Version string is baked in at build time; cache once.
775+
static CACHED: OnceLock<Arc<str>> = OnceLock::new();
776+
Ok(CACHED
777+
.get_or_init(|| {
778+
Arc::<str>::from(format!(
779+
"forest/{}",
780+
*crate::utils::version::FOREST_VERSION_STRING
781+
))
782+
})
783+
.clone())
778784
}
779785
}
780786

@@ -844,14 +850,18 @@ impl RpcMethod<0> for EthChainId {
844850
const PERMISSION: Permission = Permission::Read;
845851

846852
type Params = ();
847-
type Ok = String;
853+
type Ok = Arc<str>;
848854

849855
async fn handle(
850856
ctx: Ctx<impl Blockstore + Send + Sync + 'static>,
851857
(): Self::Params,
852858
_: &http::Extensions,
853859
) -> Result<Self::Ok, ServerError> {
854-
Ok(format!("{:#x}", ctx.chain_config().eth_chain_id))
860+
// `eth_chain_id` is fixed for the process lifetime; cache the hex form.
861+
static CACHED: OnceLock<Arc<str>> = OnceLock::new();
862+
Ok(CACHED
863+
.get_or_init(|| Arc::<str>::from(format!("{:#x}", ctx.chain_config().eth_chain_id)))
864+
.clone())
855865
}
856866
}
857867

src/rpc/methods/f3.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,20 @@ impl RpcMethod<0> for GetRawNetworkName {
6363
const PERMISSION: Permission = Permission::Read;
6464

6565
type Params = ();
66-
type Ok = String;
66+
type Ok = Arc<str>;
6767

6868
async fn handle(
6969
ctx: Ctx<impl Blockstore>,
7070
(): Self::Params,
7171
_: &http::Extensions,
7272
) -> Result<Self::Ok, ServerError> {
73-
Ok(ctx.chain_config().network.genesis_name().into())
73+
// Network is fixed for the process lifetime; cache the genesis name.
74+
static CACHED: OnceLock<Arc<str>> = OnceLock::new();
75+
Ok(CACHED
76+
.get_or_init(|| {
77+
Arc::<str>::from(String::from(ctx.chain_config().network.genesis_name()))
78+
})
79+
.clone())
7480
}
7581
}
7682

src/rpc/methods/net.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ pub use types::*;
77
use std::any::Any;
88
use std::num::NonZeroU64;
99
use std::str::FromStr;
10+
use std::sync::{Arc, OnceLock};
1011
use std::time::Instant;
1112

1213
use crate::libp2p::chain_exchange::TipsetBundle;
@@ -282,14 +283,18 @@ impl RpcMethod<0> for NetVersion {
282283
const NAME_ALIAS: Option<&'static str> = Some("net_version");
283284

284285
type Params = ();
285-
type Ok = String;
286+
type Ok = Arc<str>;
286287

287288
async fn handle(
288289
ctx: Ctx<impl Blockstore>,
289290
(): Self::Params,
290291
_: &http::Extensions,
291292
) -> Result<Self::Ok, ServerError> {
292-
Ok(ctx.chain_config().eth_chain_id.to_string())
293+
// `eth_chain_id` is fixed for the process lifetime; cache the decimal form.
294+
static CACHED: OnceLock<Arc<str>> = OnceLock::new();
295+
Ok(CACHED
296+
.get_or_init(|| Arc::<str>::from(ctx.chain_config().eth_chain_id.to_string()))
297+
.clone())
293298
}
294299
}
295300

0 commit comments

Comments
 (0)