Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions src/lotus_json/arc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,25 @@ impl<T: HasLotusJson + Clone> HasLotusJson for Arc<T> {
Arc::new(T::from_lotus_json(lotus_json))
}
}

// `Arc<str>` can't reuse the blanket impl above (which requires `T: Sized`,
// and `str` is not). `Arc<str>` already satisfies every `HasLotusJson`
// consumer bound directly (`Serialize + DeserializeOwned + JsonSchema +
// Clone + 'static`), so we make `LotusJson = Self` and keep the conversions
// as identity — serializing the cached value takes no allocation.
impl HasLotusJson for Arc<str> {
type LotusJson = Self;

#[cfg(test)]
fn snapshots() -> Vec<(serde_json::Value, Self)> {
unimplemented!("tests are trivial for HasLotusJson<LotusJson = Self>")
}

fn into_lotus_json(self) -> Self::LotusJson {
self
}

fn from_lotus_json(lotus_json: Self::LotusJson) -> Self {
lotus_json
}
}
26 changes: 18 additions & 8 deletions src/rpc/methods/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ use serde::{Deserialize, Serialize};
use std::num::NonZeroUsize;
use std::ops::RangeInclusive;
use std::str::FromStr;
use std::sync::{Arc, LazyLock};
use std::sync::{Arc, LazyLock, OnceLock};
use utils::{decode_payload, lookup_eth_address};

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

type Params = ();
type Ok = String;
type Ok = Arc<str>;

async fn handle(
_: Ctx<impl Blockstore + Send + Sync + 'static>,
(): Self::Params,
_: &http::Extensions,
) -> Result<Self::Ok, ServerError> {
Ok(format!(
"forest/{}",
*crate::utils::version::FOREST_VERSION_STRING
))
// Version string is baked in at build time; cache once.
static CACHED: OnceLock<Arc<str>> = OnceLock::new();
Ok(CACHED
.get_or_init(|| {
Arc::<str>::from(format!(
"forest/{}",
*crate::utils::version::FOREST_VERSION_STRING
))
})
.clone())
}
}

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

type Params = ();
type Ok = String;
type Ok = Arc<str>;

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

Expand Down
10 changes: 8 additions & 2 deletions src/rpc/methods/f3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,14 +63,20 @@ impl RpcMethod<0> for GetRawNetworkName {
const PERMISSION: Permission = Permission::Read;

type Params = ();
type Ok = String;
type Ok = Arc<str>;

async fn handle(
ctx: Ctx<impl Blockstore>,
(): Self::Params,
_: &http::Extensions,
) -> Result<Self::Ok, ServerError> {
Ok(ctx.chain_config().network.genesis_name().into())
// Network is fixed for the process lifetime; cache the genesis name.
static CACHED: OnceLock<Arc<str>> = OnceLock::new();
Ok(CACHED
.get_or_init(|| {
Arc::<str>::from(String::from(ctx.chain_config().network.genesis_name()))
})
.clone())
}
}

Expand Down
9 changes: 7 additions & 2 deletions src/rpc/methods/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub use types::*;
use std::any::Any;
use std::num::NonZeroU64;
use std::str::FromStr;
use std::sync::{Arc, OnceLock};
use std::time::Instant;

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

type Params = ();
type Ok = String;
type Ok = Arc<str>;

async fn handle(
ctx: Ctx<impl Blockstore>,
(): Self::Params,
_: &http::Extensions,
) -> Result<Self::Ok, ServerError> {
Ok(ctx.chain_config().eth_chain_id.to_string())
// `eth_chain_id` is fixed for the process lifetime; cache the decimal form.
static CACHED: OnceLock<Arc<str>> = OnceLock::new();
Ok(CACHED
.get_or_init(|| Arc::<str>::from(ctx.chain_config().eth_chain_id.to_string()))
.clone())
}
}

Expand Down
Loading