mithril_common/messages/
snapshot.rs1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3
4use crate::entities::{CardanoDbBeacon, CompressionAlgorithm};
5
6#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
8pub struct SnapshotMessage {
9 pub digest: String,
11
12 pub network: String,
14
15 pub beacon: CardanoDbBeacon,
17
18 pub certificate_hash: String,
20
21 pub size: u64,
23
24 #[serde(skip_serializing_if = "Option::is_none")]
26 pub ancillary_size: Option<u64>,
27
28 pub created_at: DateTime<Utc>,
30
31 pub locations: Vec<String>,
33
34 #[serde(skip_serializing_if = "Option::is_none")]
36 pub ancillary_locations: Option<Vec<String>>,
37
38 pub compression_algorithm: CompressionAlgorithm,
40
41 pub cardano_node_version: String,
43}
44
45impl SnapshotMessage {
46 pub fn compute_total_size(&self) -> u64 {
48 self.size + self.ancillary_size.unwrap_or(0)
49 }
50}
51
52#[cfg(test)]
53mod tests {
54 use crate::entities::Epoch;
55 use crate::test::double::Dummy;
56
57 use super::*;
58
59 #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
60 pub struct SnapshotMessageUntilV0_1_47 {
61 pub digest: String,
62 pub network: String,
63 pub beacon: CardanoDbBeacon,
64 pub certificate_hash: String,
65 pub size: u64,
66 pub created_at: DateTime<Utc>,
67 pub locations: Vec<String>,
68 pub compression_algorithm: CompressionAlgorithm,
69 pub cardano_node_version: String,
70 }
71
72 const CURRENT_JSON: &str = r#"{
73 "digest": "0b9f5ad7f33cc523775c82249294eb8a1541d54f08eb3107cafc5638403ec7c6",
74 "network": "preview",
75 "beacon": {
76 "epoch": 86,
77 "immutable_file_number": 1728
78 },
79 "certificate_hash": "d5daf6c03ace4a9c074e951844075b9b373bafc4e039160e3e2af01823e9abfb",
80 "size": 807803196,
81 "ancillary_size": 123456789,
82 "created_at": "2023-01-19T13:43:05.618857482Z",
83 "locations": [
84 "https://host/certificate.tar.gz"
85 ],
86 "ancillary_locations": [
87 "https://host/ancillary.tar.gz"
88 ],
89 "compression_algorithm": "gzip",
90 "cardano_node_version": "0.0.1"
91 }"#;
92
93 fn golden_message_until_open_api_0_1_47() -> SnapshotMessageUntilV0_1_47 {
94 SnapshotMessageUntilV0_1_47 {
95 digest: "0b9f5ad7f33cc523775c82249294eb8a1541d54f08eb3107cafc5638403ec7c6".to_string(),
96 network: "preview".to_string(),
97 beacon: CardanoDbBeacon {
98 epoch: Epoch(86),
99 immutable_file_number: 1728,
100 },
101 certificate_hash: "d5daf6c03ace4a9c074e951844075b9b373bafc4e039160e3e2af01823e9abfb"
102 .to_string(),
103 size: 807803196,
104 created_at: DateTime::parse_from_rfc3339("2023-01-19T13:43:05.618857482Z")
105 .unwrap()
106 .with_timezone(&Utc),
107 locations: vec!["https://host/certificate.tar.gz".to_string()],
108 compression_algorithm: CompressionAlgorithm::Gzip,
109 cardano_node_version: "0.0.1".to_string(),
110 }
111 }
112
113 fn golden_message_current() -> SnapshotMessage {
114 SnapshotMessage {
115 digest: "0b9f5ad7f33cc523775c82249294eb8a1541d54f08eb3107cafc5638403ec7c6".to_string(),
116 network: "preview".to_string(),
117 beacon: CardanoDbBeacon {
118 epoch: Epoch(86),
119 immutable_file_number: 1728,
120 },
121 certificate_hash: "d5daf6c03ace4a9c074e951844075b9b373bafc4e039160e3e2af01823e9abfb"
122 .to_string(),
123 size: 807803196,
124 ancillary_size: Some(123456789),
125 created_at: DateTime::parse_from_rfc3339("2023-01-19T13:43:05.618857482Z")
126 .unwrap()
127 .with_timezone(&Utc),
128 locations: vec!["https://host/certificate.tar.gz".to_string()],
129 ancillary_locations: Some(vec!["https://host/ancillary.tar.gz".to_string()]),
130 compression_algorithm: CompressionAlgorithm::Gzip,
131 cardano_node_version: "0.0.1".to_string(),
132 }
133 }
134
135 #[test]
136 fn test_current_json_deserialized_into_message_supported_until_open_api_0_1_47() {
137 let json = CURRENT_JSON;
138 let message: SnapshotMessageUntilV0_1_47 = serde_json::from_str(json).unwrap();
139
140 assert_eq!(golden_message_until_open_api_0_1_47(), message);
141 }
142
143 #[test]
144 fn test_current_json_deserialized_into_current_message() {
145 let json = CURRENT_JSON;
146 let message: SnapshotMessage = serde_json::from_str(json).unwrap();
147
148 assert_eq!(golden_message_current(), message);
149 }
150
151 #[test]
152 fn compute_total_size_with_ancillary_size() {
153 let message = SnapshotMessage {
154 size: 12,
155 ancillary_size: Some(33),
156 ..SnapshotMessage::dummy()
157 };
158
159 assert_eq!(message.compute_total_size(), 45);
160 }
161
162 #[test]
163 fn compute_total_size_without_ancillary_size() {
164 let message = SnapshotMessage {
165 size: 12,
166 ancillary_size: None,
167 ..SnapshotMessage::dummy()
168 };
169
170 assert_eq!(message.compute_total_size(), 12);
171 }
172}