forest/chain/
snapshot_format.rs1use crate::lotus_json::lotus_json_with_self;
5use cid::Cid;
6use itertools::Itertools as _;
7use num::FromPrimitive as _;
8use num_derive::FromPrimitive;
9use nunny::Vec as NonEmpty;
10use schemars::JsonSchema;
11use serde::{Deserialize, Serialize};
12
13#[derive(Debug, Copy, clap::ValueEnum, FromPrimitive, Clone, PartialEq, Eq, JsonSchema)]
14#[repr(u64)]
15pub enum FilecoinSnapshotVersion {
16 V1 = 1,
17 V2 = 2,
18}
19lotus_json_with_self!(FilecoinSnapshotVersion);
20
21impl Serialize for FilecoinSnapshotVersion {
22 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
23 where
24 S: serde::Serializer,
25 {
26 serializer.serialize_u64(*self as u64)
27 }
28}
29
30impl<'de> Deserialize<'de> for FilecoinSnapshotVersion {
31 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
32 where
33 D: serde::Deserializer<'de>,
34 {
35 let i = u64::deserialize(deserializer)?;
36 match FilecoinSnapshotVersion::from_u64(i) {
37 Some(v) => Ok(v),
38 None => Err(serde::de::Error::custom(format!(
39 "invalid snapshot version {i}"
40 ))),
41 }
42 }
43}
44
45#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
47#[serde(rename_all = "PascalCase")]
48pub struct FilecoinSnapshotMetadata {
49 pub version: FilecoinSnapshotVersion,
51 pub head_tipset_key: NonEmpty<Cid>,
53 pub f3_data: Option<Cid>,
55}
56
57impl FilecoinSnapshotMetadata {
58 pub fn new(
59 version: FilecoinSnapshotVersion,
60 head_tipset_key: NonEmpty<Cid>,
61 f3_data: Option<Cid>,
62 ) -> Self {
63 Self {
64 version,
65 head_tipset_key,
66 f3_data,
67 }
68 }
69
70 pub fn new_v2(head_tipset_key: NonEmpty<Cid>, f3_data: Option<Cid>) -> Self {
71 Self::new(FilecoinSnapshotVersion::V2, head_tipset_key, f3_data)
72 }
73}
74
75impl std::fmt::Display for FilecoinSnapshotMetadata {
76 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
77 writeln!(f, "Snapshot version: {}", self.version as u64)?;
78 let head_tipset_key_string = self
79 .head_tipset_key
80 .iter()
81 .map(Cid::to_string)
82 .join("\n ");
83 writeln!(f, "Head Tipset: {head_tipset_key_string}")?;
84 write!(
85 f,
86 "F3 data: {}",
87 self.f3_data
88 .map(|c| c.to_string())
89 .unwrap_or_else(|| "not found".into())
90 )?;
91 Ok(())
92 }
93}