bee_ledger/types/snapshot/
header.rs

1// Copyright 2020-2021 IOTA Stiftung
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::types::{error::Error, snapshot::SnapshotKind};
5
6use bee_common::packable::{Packable, Read, Write};
7use bee_message::{milestone::MilestoneIndex, payload::milestone::MilestoneId};
8
9const SNAPSHOT_VERSION: u8 = 1;
10
11/// Describes a snapshot header common to full and delta snapshots.
12#[derive(Clone)]
13pub struct SnapshotHeader {
14    kind: SnapshotKind,
15    timestamp: u64,
16    network_id: u64,
17    sep_index: MilestoneIndex,
18    ledger_index: MilestoneIndex,
19}
20
21impl SnapshotHeader {
22    /// The length, in bytes, of a `SnapshotHeader`.
23    pub const LENGTH: usize = 26;
24
25    /// Returns the kind of a `SnapshotHeader`.
26    pub fn kind(&self) -> SnapshotKind {
27        self.kind
28    }
29
30    /// Returns the timestamp of a `SnapshotHeader`.
31    pub fn timestamp(&self) -> u64 {
32        self.timestamp
33    }
34
35    /// Returns the network id of a `SnapshotHeader`.
36    pub fn network_id(&self) -> u64 {
37        self.network_id
38    }
39
40    /// Returns the solid entry point index of a `SnapshotHeader`.
41    pub fn sep_index(&self) -> MilestoneIndex {
42        self.sep_index
43    }
44
45    /// Returns the ledger index of a `SnapshotHeader`.
46    pub fn ledger_index(&self) -> MilestoneIndex {
47        self.ledger_index
48    }
49}
50
51impl Packable for SnapshotHeader {
52    type Error = Error;
53
54    fn packed_len(&self) -> usize {
55        SNAPSHOT_VERSION.packed_len()
56            + self.kind.packed_len()
57            + self.timestamp.packed_len()
58            + self.network_id.packed_len()
59            + self.sep_index.packed_len()
60            + self.ledger_index.packed_len()
61    }
62
63    fn pack<W: Write>(&self, writer: &mut W) -> Result<(), Self::Error> {
64        SNAPSHOT_VERSION.pack(writer)?;
65        self.kind.pack(writer)?;
66        self.timestamp.pack(writer)?;
67        self.network_id.pack(writer)?;
68        self.sep_index.pack(writer)?;
69        self.ledger_index.pack(writer)?;
70
71        Ok(())
72    }
73
74    fn unpack_inner<R: Read + ?Sized, const CHECK: bool>(reader: &mut R) -> Result<Self, Self::Error> {
75        let version = u8::unpack_inner::<R, CHECK>(reader)?;
76
77        if CHECK && SNAPSHOT_VERSION != version {
78            return Err(Self::Error::UnsupportedVersion(SNAPSHOT_VERSION, version));
79        }
80
81        let kind = SnapshotKind::unpack_inner::<R, CHECK>(reader)?;
82        let timestamp = u64::unpack_inner::<R, CHECK>(reader)?;
83        let network_id = u64::unpack_inner::<R, CHECK>(reader)?;
84        let sep_index = MilestoneIndex::unpack_inner::<R, CHECK>(reader)?;
85        let ledger_index = MilestoneIndex::unpack_inner::<R, CHECK>(reader)?;
86
87        Ok(Self {
88            kind,
89            timestamp,
90            network_id,
91            sep_index,
92            ledger_index,
93        })
94    }
95}
96
97/// Describes a snapshot header specific to full snapshots.
98#[derive(Clone)]
99pub struct FullSnapshotHeader {
100    sep_count: u64,
101    output_count: u64,
102    milestone_diff_count: u64,
103    treasury_output_milestone_id: MilestoneId,
104    treasury_output_amount: u64,
105}
106
107impl FullSnapshotHeader {
108    /// Returns the solid entry point count of a `FullSnapshotHeader`.
109    pub fn sep_count(&self) -> u64 {
110        self.sep_count
111    }
112
113    /// Returns the output count of a `FullSnapshotHeader`.
114    pub fn output_count(&self) -> u64 {
115        self.output_count
116    }
117
118    /// Returns the milestone diff count of a `FullSnapshotHeader`.
119    pub fn milestone_diff_count(&self) -> u64 {
120        self.milestone_diff_count
121    }
122
123    /// Returns the treasury output milestone id of a `FullSnapshotHeader`.
124    pub fn treasury_output_milestone_id(&self) -> &MilestoneId {
125        &self.treasury_output_milestone_id
126    }
127
128    /// Returns the treasury output amount of a `FullSnapshotHeader`.
129    pub fn treasury_output_amount(&self) -> u64 {
130        self.treasury_output_amount
131    }
132}
133
134impl Packable for FullSnapshotHeader {
135    type Error = Error;
136
137    fn packed_len(&self) -> usize {
138        self.sep_count.packed_len()
139            + self.output_count.packed_len()
140            + self.milestone_diff_count.packed_len()
141            + self.treasury_output_milestone_id.packed_len()
142            + self.treasury_output_amount.packed_len()
143    }
144
145    fn pack<W: Write>(&self, writer: &mut W) -> Result<(), Self::Error> {
146        self.sep_count.pack(writer)?;
147        self.output_count.pack(writer)?;
148        self.milestone_diff_count.pack(writer)?;
149        self.treasury_output_milestone_id.pack(writer)?;
150        self.treasury_output_amount.pack(writer)?;
151
152        Ok(())
153    }
154
155    fn unpack_inner<R: Read + ?Sized, const CHECK: bool>(reader: &mut R) -> Result<Self, Self::Error> {
156        let sep_count = u64::unpack_inner::<R, CHECK>(reader)?;
157        let output_count = u64::unpack_inner::<R, CHECK>(reader)?;
158        let milestone_diff_count = u64::unpack_inner::<R, CHECK>(reader)?;
159        let treasury_output_milestone_id = MilestoneId::unpack_inner::<R, CHECK>(reader)?;
160        let treasury_output_amount = u64::unpack_inner::<R, CHECK>(reader)?;
161
162        Ok(Self {
163            sep_count,
164            output_count,
165            milestone_diff_count,
166            treasury_output_milestone_id,
167            treasury_output_amount,
168        })
169    }
170}
171
172/// Describes a snapshot header specific to delta snapshots.
173#[derive(Clone)]
174pub struct DeltaSnapshotHeader {
175    sep_count: u64,
176    milestone_diff_count: u64,
177}
178
179impl DeltaSnapshotHeader {
180    /// Returns the solid entry point count of a `DeltaSnapshotHeader`.
181    pub fn sep_count(&self) -> u64 {
182        self.sep_count
183    }
184
185    /// Returns the milestone diff count of a `DeltaSnapshotHeader`.
186    pub fn milestone_diff_count(&self) -> u64 {
187        self.milestone_diff_count
188    }
189}
190
191impl Packable for DeltaSnapshotHeader {
192    type Error = Error;
193
194    fn packed_len(&self) -> usize {
195        self.sep_count.packed_len() + self.milestone_diff_count.packed_len()
196    }
197
198    fn pack<W: Write>(&self, writer: &mut W) -> Result<(), Self::Error> {
199        self.sep_count.pack(writer)?;
200        self.milestone_diff_count.pack(writer)?;
201
202        Ok(())
203    }
204
205    fn unpack_inner<R: Read + ?Sized, const CHECK: bool>(reader: &mut R) -> Result<Self, Self::Error> {
206        let sep_count = u64::unpack_inner::<R, CHECK>(reader)?;
207        let milestone_diff_count = u64::unpack_inner::<R, CHECK>(reader)?;
208
209        Ok(Self {
210            sep_count,
211            milestone_diff_count,
212        })
213    }
214}