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
2 changes: 1 addition & 1 deletion src/chain_sync/chain_muxer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

use serde::{Deserialize, Serialize};

const DEFAULT_RECENT_STATE_ROOTS: i64 = 2000;
pub const DEFAULT_RECENT_STATE_ROOTS: i64 = 2000;

/// Structure that defines syncing configuration options
#[derive(Debug, Deserialize, Serialize, Clone, PartialEq, Eq)]
Expand Down
2 changes: 1 addition & 1 deletion src/chain_sync/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

mod bad_block_cache;
mod chain_follower;
mod chain_muxer;
pub mod chain_muxer;
pub mod consensus;
pub mod metrics;
pub mod network_context;
Expand Down
46 changes: 31 additions & 15 deletions src/cli/subcommands/snapshot_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
// SPDX-License-Identifier: Apache-2.0, MIT

use crate::chain::FilecoinSnapshotVersion;
use crate::chain_sync::SyncConfig;
use crate::chain_sync::chain_muxer::DEFAULT_RECENT_STATE_ROOTS;
use crate::cli_shared::snapshot::{self, TrustedVendor};
use crate::db::car::forest::new_forest_car_temp_path_in;
use crate::networks::calibnet;
use crate::rpc::chain::ForestChainExportDiffParams;
use crate::rpc::{self, chain::ForestChainExportParams, prelude::*, types::ApiTipsetKey};
use crate::rpc::{self, chain::ForestChainExportParams, prelude::*};
use crate::shim::policy::policy_constants::CHAIN_FINALITY;
use anyhow::Context as _;
use chrono::DateTime;
use clap::Subcommand;
Expand All @@ -34,10 +35,10 @@ pub enum SnapshotCommands {
/// Tipset to start the export from, default is the chain head
#[arg(short, long)]
tipset: Option<i64>,
/// How many state-roots to include. Lower limit is 900 for `calibnet` and `mainnet`.
#[arg(short, long)]
depth: Option<crate::chain::ChainEpochDelta>,
/// Export snapshot in the experimental v2 format(FRC-0108).
/// How many state trees to include. 0 for chain spine with no state trees.
#[arg(short, long, default_value_t = DEFAULT_RECENT_STATE_ROOTS)]
depth: crate::chain::ChainEpochDelta,
/// Snapshot format to export.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
#[arg(long, value_enum, default_value_t = FilecoinSnapshotVersion::V1)]
format: FilecoinSnapshotVersion,
},
Expand Down Expand Up @@ -69,12 +70,18 @@ impl SnapshotCommands {
depth,
format,
} => {
let chain_head = ChainHead::call(&client, ()).await?;
anyhow::ensure!(
depth >= 0,
"--depth must be non-negative; use 0 for spine-only snapshots"
);

let epoch = tipset.unwrap_or(chain_head.epoch());
if depth < CHAIN_FINALITY {
tracing::warn!(
"Depth {depth} should be no less than CHAIN_FINALITY {CHAIN_FINALITY} to export a valid lite snapshot"
);
}

let raw_network_name = StateNetworkName::call(&client, ()).await?;

// For historical reasons and backwards compatibility if snapshot services or their
// consumers relied on the `calibnet`, we use `calibnet` as the chain name.
let chain_name = if raw_network_name == calibnet::NETWORK_GENESIS_NAME {
Expand All @@ -83,8 +90,17 @@ impl SnapshotCommands {
raw_network_name.as_str()
};

let tipset =
ChainGetTipSetByHeight::call(&client, (epoch, Default::default())).await?;
let tipset = if let Some(epoch) = tipset {
// This could take a while when the requested epoch is far behind the chain head
client
.call(
ChainGetTipSetByHeight::request((epoch, Default::default()))?
.with_timeout(Duration::from_secs(60 * 15)),
)
.await?
} else {
ChainHead::call(&client, ()).await?
};

let output_path = match output_path.is_dir() {
true => output_path.join(snapshot::filename(
Expand All @@ -94,7 +110,7 @@ impl SnapshotCommands {
.unwrap_or_default()
.naive_utc()
.date(),
epoch,
tipset.epoch(),
true,
)),
false => output_path.clone(),
Expand All @@ -105,10 +121,10 @@ impl SnapshotCommands {

let params = ForestChainExportParams {
version: format,
epoch,
recent_roots: depth.unwrap_or(SyncConfig::default().recent_state_roots),
epoch: tipset.epoch(),
recent_roots: depth,
output_path: temp_path.to_path_buf(),
tipset_keys: ApiTipsetKey(Some(chain_head.key().clone())),
tipset_keys: tipset.key().clone().into(),
skip_checksum,
dry_run,
};
Expand Down
8 changes: 0 additions & 8 deletions src/rpc/methods/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -332,14 +332,6 @@ impl RpcMethod<1> for ForestChainExport {
return Err(anyhow::anyhow!("Another chain export job is still in progress").into());
}

let chain_finality = ctx.chain_config().policy.chain_finality;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's still worth putting a warning. Zero-depth snapshots are a niche use case.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a warning on the client(forest-cli) side.

if recent_roots < chain_finality {
return Err(anyhow::anyhow!(format!(
"recent-stateroots must be greater than {chain_finality}"
))
.into());
}

let head = ctx.chain_store().load_required_tipset_or_heaviest(&tsk)?;
let start_ts =
ctx.chain_index()
Expand Down
Loading