Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
7 changes: 6 additions & 1 deletion src/auth/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright 2019-2026 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

use std::sync::LazyLock;

use crate::key_management::KeyInfo;
use crate::shim::crypto::SignatureType;
use crate::utils::misc::env::is_env_truthy;
Expand Down Expand Up @@ -42,8 +44,11 @@ pub fn create_token(perms: Vec<String>, key: &[u8], token_exp: Duration) -> JWTR

/// Verify JWT Token and return the allowed permissions from token
pub fn verify_token(token: &str, key: &[u8]) -> JWTResult<Vec<String>> {
static DISABLE_EXP_VALIDATION: LazyLock<bool> =
LazyLock::new(|| is_env_truthy("FOREST_JWT_DISABLE_EXP_VALIDATION"));

let mut validation = jsonwebtoken::Validation::new(jsonwebtoken::Algorithm::default());
if is_env_truthy("FOREST_JWT_DISABLE_EXP_VALIDATION") {
if *DISABLE_EXP_VALIDATION {
let mut claims = validation.required_spec_claims.clone();
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
claims.remove("exp");
let buff: Vec<_> = claims.iter().collect();
Expand Down
5 changes: 5 additions & 0 deletions src/beacon/drand.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright 2019-2026 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

use std::sync::LazyLock;
use std::time::Duration;
use std::{borrow::Cow, num::NonZeroUsize};

Expand All @@ -13,6 +14,7 @@ use super::{
use crate::shim::clock::ChainEpoch;
use crate::shim::version::NetworkVersion;
use crate::utils::cache::SizeTrackingLruCache;
use crate::utils::misc::env::is_env_truthy;
use crate::utils::net::global_http_client;
use anyhow::Context as _;
use backon::{ExponentialBuilder, Retryable};
Expand All @@ -28,6 +30,9 @@ use url::Url;
/// `LOTUS_IGNORE_DRAND`
pub const IGNORE_DRAND_VAR: &str = "FOREST_IGNORE_DRAND";

/// Whether to ignore `Drand`.
pub static IGNORE_DRAND: LazyLock<bool> = LazyLock::new(|| is_env_truthy(IGNORE_DRAND_VAR));

/// Type of the `drand` network. `mainnet` is chained and `quicknet` is unchained.
/// For the details, see <https://github.com/filecoin-project/FIPs/blob/1bd887028ac1b50b6f2f94913e07ede73583da5b/FIPS/fip-0063.md#specification>
#[derive(PartialEq, Eq, Copy, Clone, Debug, SerdeSerialize, SerdeDeserialize)]
Expand Down
27 changes: 8 additions & 19 deletions src/chain/store/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
use std::num::NonZeroUsize;
use std::sync::LazyLock;

use crate::beacon::{BeaconEntry, IGNORE_DRAND_VAR};
use crate::beacon::{BeaconEntry, IGNORE_DRAND};
use crate::blocks::{Tipset, TipsetKey};
use crate::chain::Error;
use crate::metrics;
Expand All @@ -16,7 +16,7 @@ use itertools::Itertools;
use nonzero_ext::nonzero;
use num::Integer;

const DEFAULT_TIPSET_CACHE_SIZE: NonZeroUsize = nonzero!(131072_usize);
const DEFAULT_TIPSET_CACHE_SIZE: NonZeroUsize = nonzero!(2880_usize);

type TipsetCache = SizeTrackingLruCache<TipsetKey, Tipset>;

Expand Down Expand Up @@ -52,16 +52,17 @@ impl<DB: Blockstore> ChainIndex<DB> {
/// Loads a tipset from memory given the tipset keys and cache. Semantically
/// identical to [`Tipset::load`] but the result is cached.
pub fn load_tipset(&self, tsk: &TipsetKey) -> Result<Option<Tipset>, Error> {
let cache_enabled = !is_env_truthy("FOREST_TIPSET_CACHE_DISABLED");
if cache_enabled && let Some(ts) = self.ts_cache.get_cloned(tsk) {
static CACHE_ENABLED: LazyLock<bool> =
LazyLock::new(|| !is_env_truthy("FOREST_TIPSET_CACHE_DISABLED"));
if *CACHE_ENABLED && let Some(ts) = self.ts_cache.get_cloned(tsk) {
metrics::LRU_CACHE_HIT
.get_or_create(&metrics::values::TIPSET)
.inc();
return Ok(Some(ts));
}

let ts_opt = Tipset::load(&self.db, tsk)?;
if cache_enabled && let Some(ts) = &ts_opt {
if *CACHE_ENABLED && let Some(ts) = &ts_opt {
self.ts_cache.push(tsk.clone(), ts.clone());
metrics::LRU_CACHE_MISS
.get_or_create(&metrics::values::TIPSET)
Expand Down Expand Up @@ -162,7 +163,7 @@ impl<DB: Blockstore> ChainIndex<DB> {
)));
}

for (child, parent) in self.chain(from).tuple_windows() {
for (child, parent) in from.chain(&self.db).tuple_windows() {
// use `child.epoch() + CHAIN_FINALITY <= from_epoch`
// to ensure the cached child is finalized(not on a fork).
if child.epoch() % CHAIN_FINALITY == 0 && child.epoch() + CHAIN_FINALITY <= from_epoch {
Expand All @@ -185,18 +186,6 @@ impl<DB: Blockstore> ChainIndex<DB> {
)))
}

/// Iterate from the given tipset to genesis. Missing tipsets cut the chain
/// short. Semantically identical to [`Tipset::chain`] but the results are
/// cached.
pub fn chain(&self, from: Tipset) -> impl Iterator<Item = Tipset> + '_ {
let mut tipset = Some(from);
std::iter::from_fn(move || {
let child = tipset.take()?;
tipset = self.load_required_tipset(child.parents()).ok();
Comment thread
hanabi1224 marked this conversation as resolved.
Some(child)
})
}

/// Finds the latest beacon entry given a tipset up to 20 tipsets behind
pub fn latest_beacon_entry(&self, tipset: Tipset) -> Result<BeaconEntry, Error> {
for ts in tipset.chain(&self.db).take(20) {
Expand All @@ -210,7 +199,7 @@ impl<DB: Blockstore> ChainIndex<DB> {
}
}

if is_env_truthy(IGNORE_DRAND_VAR) {
if *IGNORE_DRAND {
return Ok(BeaconEntry::new(0, vec![9; 16]));
}

Expand Down
10 changes: 7 additions & 3 deletions src/chain_sync/chain_follower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,10 @@ use fvm_ipld_blockstore::Blockstore;
use itertools::Itertools;
use libp2p::PeerId;
use parking_lot::{Mutex, RwLock};
use std::{sync::Arc, time::Instant};
use std::{
sync::{Arc, LazyLock},
time::Instant,
};
use tokio::{sync::Notify, task::JoinSet};
use tracing::{debug, error, info, trace, warn};

Expand Down Expand Up @@ -90,14 +93,15 @@ impl<DB: Blockstore + Sync + Send + 'static> ChainFollower<DB> {
stateless_mode: bool,
mem_pool: Arc<MessagePool<Arc<ChainStore<DB>>>>,
) -> Self {
static DISABLE_BAD_BLOCK_CACHE: LazyLock<bool> =
LazyLock::new(|| is_env_truthy("FOREST_DISABLE_BAD_BLOCK_CACHE"));
let (tipset_sender, tipset_receiver) = flume::bounded(20);
let disable_bad_block_cache = is_env_truthy("FOREST_DISABLE_BAD_BLOCK_CACHE");
Self {
sync_status: Arc::new(RwLock::new(SyncStatusReport::init())),
state_manager,
network,
genesis,
bad_blocks: if disable_bad_block_cache {
bad_blocks: if *DISABLE_BAD_BLOCK_CACHE {
tracing::warn!("bad block cache is disabled by `FOREST_DISABLE_BAD_BLOCK_CACHE`");
None
} else {
Expand Down
4 changes: 2 additions & 2 deletions src/cli_shared/cli/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::db::db_engine::DbConfig;
use crate::libp2p::Libp2pConfig;
use crate::shim::clock::ChainEpoch;
use crate::shim::econ::TokenAmount;
use crate::utils::misc::env::is_env_set_and_truthy;
use crate::utils::misc::env::is_env_truthy;
use crate::{chain_sync::SyncConfig, networks::NetworkChain};
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
Expand Down Expand Up @@ -86,7 +86,7 @@ pub struct ChainIndexerConfig {
impl Default for ChainIndexerConfig {
fn default() -> Self {
Self {
enable_indexer: is_env_set_and_truthy(FOREST_CHAIN_INDEXER_ENABLED).unwrap_or(false),
enable_indexer: is_env_truthy(FOREST_CHAIN_INDEXER_ENABLED),
gc_retention_epochs: None,
}
}
Expand Down
13 changes: 7 additions & 6 deletions src/dev/subcommands/state_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// SPDX-License-Identifier: Apache-2.0, MIT

use crate::{
blocks::Tipset,
chain::{ChainStore, index::ResolveNullTipset},
chain_sync::{load_full_tipset, tipset_syncer::validate_tipset},
cli_shared::{chain_path, read_config},
Expand Down Expand Up @@ -82,10 +81,11 @@ impl ComputeCommand {
chain_config,
genesis_header,
)?);
let chain_index = chain_store.chain_index();
let (ts, ts_next) = {
// We don't want to track all entries that are visited by `tipset_by_height`
db.pause_tracking();
let ts = chain_store.chain_index().tipset_by_height(
let ts = chain_index.tipset_by_height(
epoch,
chain_store.heaviest_tipset(),
ResolveNullTipset::TakeOlder,
Expand All @@ -99,8 +99,8 @@ impl ComputeCommand {
)?;
// Only track the desired tipsets
(
Tipset::load_required(&db, ts.key())?,
Tipset::load_required(&db, ts_next.key())?,
chain_index.load_required_tipset(ts.key())?,
chain_index.load_required_tipset(ts_next.key())?,
)
};
let epoch = ts.epoch();
Expand Down Expand Up @@ -207,18 +207,19 @@ impl ValidateCommand {
chain_config,
genesis_header,
)?);
let chain_index = chain_store.chain_index();
let ts = {
// We don't want to track all entries that are visited by `tipset_by_height`
db.pause_tracking();
let ts = chain_store.chain_index().tipset_by_height(
let ts = chain_index.tipset_by_height(
epoch,
chain_store.heaviest_tipset(),
ResolveNullTipset::TakeOlder,
)?;
db.resume_tracking();
SettingsStoreExt::write_obj(&db.tracker, crate::db::setting_keys::HEAD_KEY, ts.key())?;
// Only track the desired tipset
Tipset::load_required(&db, ts.key())?
chain_index.load_required_tipset(ts.key())?
};
let epoch = ts.epoch();
let fts = load_full_tipset(&chain_store, ts.key())?;
Expand Down
10 changes: 7 additions & 3 deletions src/f3/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@

#[cfg(all(f3sidecar, not(feature = "no-f3-sidecar")))]
mod go_ffi;
use std::path::{Path, PathBuf};
use std::{
path::{Path, PathBuf},
sync::LazyLock,
};

#[cfg(all(f3sidecar, not(feature = "no-f3-sidecar")))]
use go_ffi::*;
Expand Down Expand Up @@ -146,8 +149,9 @@ pub fn import_f3_snapshot(
/// Whether F3 sidecar via FFI is enabled.
pub fn is_sidecar_ffi_enabled(chain_config: &ChainConfig) -> bool {
// Respect the environment variable when set, and fallback to chain config when not set.
let enabled =
is_env_set_and_truthy("FOREST_F3_SIDECAR_FFI_ENABLED").unwrap_or(chain_config.f3_enabled);
static ENV_ENABLED: LazyLock<Option<bool>> =
LazyLock::new(|| is_env_set_and_truthy("FOREST_F3_SIDECAR_FFI_ENABLED"));
let enabled = ENV_ENABLED.unwrap_or(chain_config.f3_enabled);
cfg_if::cfg_if! {
if #[cfg(all(f3sidecar, not(feature = "no-f3-sidecar")))] {
enabled
Expand Down
5 changes: 2 additions & 3 deletions src/fil_cns/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

use std::{collections::BTreeMap, sync::Arc};

use crate::beacon::{BeaconEntry, BeaconSchedule, IGNORE_DRAND_VAR};
use crate::beacon::{BeaconEntry, BeaconSchedule, IGNORE_DRAND};
use crate::blocks::{Block, CachingBlockHeader, Tipset};
use crate::chain::ChainStore;
use crate::chain_sync::collect_errs;
Expand All @@ -22,7 +22,6 @@ use crate::shim::{
};
use crate::state_manager::StateManager;
use crate::utils::encoding::prover_id_from_u64;
use crate::utils::misc::env::is_env_truthy;
use cid::Cid;
use fil_actors_shared::filecoin_proofs_api::{PublicReplicaInfo, SectorId, post};
use fil_actors_shared::v10::runtime::DomainSeparationTag;
Expand Down Expand Up @@ -127,7 +126,7 @@ pub(in crate::fil_cns) async fn validate_block<DB: Blockstore + Sync + Send + 's
});

// Beacon values check
if !is_env_truthy(IGNORE_DRAND_VAR) {
if !*IGNORE_DRAND {
validations.spawn({
let block = block.clone();
let parent_epoch = base_tipset.epoch();
Expand Down
5 changes: 2 additions & 3 deletions src/libp2p/chain_exchange/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,8 @@ where
}
};

let chain: Vec<_> = cs
.chain_index()
.chain(root)
let chain: Vec<_> = root
.chain(cs.blockstore())
.take(request.request_len as _)
.map(|tipset| {
let mut tipset_bundle: TipsetBundle = TipsetBundle::default();
Expand Down
4 changes: 3 additions & 1 deletion src/rpc/methods/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,9 @@ impl RpcMethod<1> for ChainGetParentMessages {
if block_header.epoch == 0 {
Ok(vec![])
} else {
let parent_tipset = Tipset::load_required(store, &block_header.parents)?;
let parent_tipset = ctx
.chain_index()
.load_required_tipset(&block_header.parents)?;
load_api_messages_from_tipset(&ctx, parent_tipset.key()).await
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/rpc/methods/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -931,7 +931,7 @@ fn get_tipset_from_hash<DB: Blockstore>(
block_hash: &EthHash,
) -> anyhow::Result<Tipset> {
let tsk = chain_store.get_required_tipset_key(block_hash)?;
Tipset::load_required(chain_store.blockstore(), &tsk)
Ok(chain_store.chain_index().load_required_tipset(&tsk)?)
}

fn resolve_block_number_tipset<DB: Blockstore>(
Expand Down
2 changes: 1 addition & 1 deletion src/rpc/methods/eth/filter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ impl EthEventHandler {
.await?;
}
ParsedFilterTipsets::Key(tsk) => {
let tipset = Arc::new(Tipset::load_required(ctx.store(), tsk)?);
let tipset = ctx.chain_index().load_required_tipset(tsk)?;
Self::collect_events(ctx, &tipset, Some(pf), skip_event, &mut collected_events)
.await?;
}
Expand Down
5 changes: 3 additions & 2 deletions src/rpc/methods/f3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -519,8 +519,9 @@ impl RpcMethod<1> for Finalize {
_: &http::Extensions,
) -> Result<Self::Ok, ServerError> {
// Respect the environment variable when set, and fallback to chain config when not set.
let enabled = is_env_set_and_truthy("FOREST_F3_CONSENSUS_ENABLED")
.unwrap_or(ctx.chain_config().f3_consensus);
static ENV_ENABLED: LazyLock<Option<bool>> =
LazyLock::new(|| is_env_set_and_truthy("FOREST_F3_CONSENSUS_ENABLED"));
let enabled = ENV_ENABLED.unwrap_or(ctx.chain_config().f3_consensus);
if !enabled {
return Ok(());
}
Expand Down
17 changes: 9 additions & 8 deletions src/state_manager/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,8 +238,8 @@ where
// validation, and it prevents duplicate migrations.
pub fn populate_cache(&self) {
for (child, parent) in self
.chain_index()
.chain(self.heaviest_tipset())
.heaviest_tipset()
.chain(self.blockstore())
.tuple_windows()
.take(DEFAULT_TIPSET_CACHE_SIZE.into())
{
Expand Down Expand Up @@ -1612,10 +1612,9 @@ where
})?;

// lookup tipset parents as we go along, iterating DOWN from `end`
let tipsets = self
.chain_index()
.chain(end)
.take_while(|tipset| tipset.epoch() >= *epochs.start());
let tipsets = end
.chain(self.blockstore())
.take_while(|ts| ts.epoch() >= *epochs.start());

self.validate_tipsets(tipsets)
}
Expand Down Expand Up @@ -1925,8 +1924,10 @@ impl<'a, DB: Blockstore + Send + Sync + 'static> TipsetExecutor<'a, DB> {
use crate::shim::clock::EPOCH_DURATION_SECONDS;

let mut parent_state = *self.tipset.parent_state();
let parent_epoch =
Tipset::load_required(self.chain_index.db(), self.tipset.parents())?.epoch();
let parent_epoch = self
.chain_index
.load_required_tipset(self.tipset.parents())?
.epoch();
let epoch = self.tipset.epoch();

for epoch_i in parent_epoch..epoch {
Expand Down
4 changes: 2 additions & 2 deletions src/tool/subcommands/snapshot_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -428,8 +428,8 @@ where
let chain_index = Arc::new(ChainIndex::new(Arc::new(db.clone())));

// Prepare tipsets for validation
let tipsets = chain_index
.chain(ts)
let tipsets = ts
.chain(&db)
.take_while(|tipset| tipset.epoch() >= last_epoch)
.inspect(|tipset| {
pb.set_message(format!("epoch queue: {}", tipset.epoch() - last_epoch));
Expand Down
6 changes: 4 additions & 2 deletions src/utils/io/mmap.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2019-2026 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

use std::{fs, io, path::Path};
use std::{fs, io, path::Path, sync::LazyLock};

use memmap2::MmapAsRawDesc;
use positioned_io::{RandomAccessFile, ReadAt, Size};
Expand Down Expand Up @@ -84,7 +84,9 @@ impl Size for EitherMmapOrRandomAccessFile {

fn should_use_file_io() -> bool {
// Use mmap by default, switch to file-io when `FOREST_CAR_LOADER_FILE_IO` is set to `1` or `true`
is_env_truthy("FOREST_CAR_LOADER_FILE_IO")
static USE_FILE_IO: LazyLock<bool> =
LazyLock::new(|| is_env_truthy("FOREST_CAR_LOADER_FILE_IO"));
*USE_FILE_IO
}

#[cfg(test)]
Expand Down
Loading
Loading