Skip to main content

forest/chain/
snapshot_format.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::prelude::*;
6use num::FromPrimitive as _;
7use num_derive::FromPrimitive;
8use nunny::Vec as NonEmpty;
9use schemars::JsonSchema;
10use serde::{Deserialize, Serialize};
11
12#[derive(Debug, Copy, clap::ValueEnum, FromPrimitive, Clone, PartialEq, Eq, JsonSchema)]
13#[repr(u64)]
14pub enum FilecoinSnapshotVersion {
15    V1 = 1,
16    V2 = 2,
17}
18lotus_json_with_self!(FilecoinSnapshotVersion);
19
20impl Serialize for FilecoinSnapshotVersion {
21    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
22    where
23        S: serde::Serializer,
24    {
25        serializer.serialize_u64(*self as u64)
26    }
27}
28
29impl<'de> Deserialize<'de> for FilecoinSnapshotVersion {
30    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
31    where
32        D: serde::Deserializer<'de>,
33    {
34        let i = u64::deserialize(deserializer)?;
35        match FilecoinSnapshotVersion::from_u64(i) {
36            Some(v) => Ok(v),
37            None => Err(serde::de::Error::custom(format!(
38                "invalid snapshot version {i}"
39            ))),
40        }
41    }
42}
43
44/// Defined in <https://github.com/filecoin-project/FIPs/blob/98e33b9fa306959aa0131519eb4cc155522b2081/FRCs/frc-0108.md#snapshotmetadata>
45#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, derive_more::Constructor)]
46#[serde(rename_all = "PascalCase")]
47pub struct FilecoinSnapshotMetadata {
48    /// Snapshot version
49    pub version: FilecoinSnapshotVersion,
50    /// Chain head tipset key
51    pub head_tipset_key: NonEmpty<Cid>,
52    /// F3 snapshot `CID`
53    pub f3_data: Option<Cid>,
54}
55
56impl FilecoinSnapshotMetadata {
57    pub fn new_v2(head_tipset_key: NonEmpty<Cid>, f3_data: Option<Cid>) -> Self {
58        Self::new(FilecoinSnapshotVersion::V2, head_tipset_key, f3_data)
59    }
60}
61
62impl std::fmt::Display for FilecoinSnapshotMetadata {
63    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
64        writeln!(f, "Snapshot version:           {}", self.version as u64)?;
65        let head_tipset_key_string = self
66            .head_tipset_key
67            .iter()
68            .map(Cid::to_string)
69            .join("\n                            ");
70        writeln!(f, "Head Tipset:                {head_tipset_key_string}")?;
71        write!(
72            f,
73            "F3 data:                    {}",
74            self.f3_data
75                .map(|c| c.to_string())
76                .unwrap_or_else(|| "not found".into())
77        )?;
78        Ok(())
79    }
80}