1#[derive(Clone, Copy, Debug, DeriveMallocSizeOf, PartialEq)]
6#[repr(u8)]
7pub enum SnapshotKeptToProvideSyncStatus {
8 No = 0,
9 InfoOnly = 1,
10 InfoAndSnapshot = 2,
11}
12
13impl Default for SnapshotKeptToProvideSyncStatus {
14 fn default() -> Self { SnapshotKeptToProvideSyncStatus::No }
15}
16
17impl Encodable for SnapshotKeptToProvideSyncStatus {
18 fn rlp_append(&self, s: &mut RlpStream) {
19 s.append_internal(&(*self as u8));
20 }
21}
22
23impl Decodable for SnapshotKeptToProvideSyncStatus {
24 fn decode(rlp: &Rlp) -> std::result::Result<Self, DecoderError> {
25 Ok(unsafe { std::mem::transmute(rlp.as_val::<u8>()?) })
26 }
27}
28
29#[derive(
30 Clone, Default, DeriveMallocSizeOf, RlpEncodable, RlpDecodable, Debug,
31)]
32pub struct SnapshotInfo {
33 pub snapshot_info_kept_to_provide_sync: SnapshotKeptToProvideSyncStatus,
36 pub serve_one_step_sync: bool,
38
39 pub merkle_root: MerkleHash,
40 pub parent_snapshot_height: u64,
41 pub height: u64,
42 pub parent_snapshot_epoch_id: EpochId,
43 #[debug(skip)]
46 pub pivot_chain_parts: Vec<EpochId>,
47}
48
49impl SnapshotInfo {
50 pub fn genesis_snapshot_info() -> Self {
51 Self {
52 snapshot_info_kept_to_provide_sync: Default::default(),
53 serve_one_step_sync: false,
54 merkle_root: MERKLE_NULL_NODE,
55 parent_snapshot_height: 0,
56 height: 0,
57 parent_snapshot_epoch_id: NULL_EPOCH,
58 pivot_chain_parts: vec![NULL_EPOCH],
59 }
60 }
61
62 pub fn get_snapshot_epoch_id(&self) -> &EpochId {
63 self.pivot_chain_parts.last().unwrap()
64 }
65
66 pub fn get_epoch_id_at_height(&self, height: u64) -> Option<&EpochId> {
67 if height < self.parent_snapshot_height {
68 None
69 } else if height == self.parent_snapshot_height {
70 Some(&self.parent_snapshot_epoch_id)
71 } else if height > self.height {
72 None
73 } else {
74 unsafe {
75 Some(self.pivot_chain_parts.get_unchecked(
76 (height - self.parent_snapshot_height - 1) as usize,
77 ))
78 }
79 }
80 }
81}
82
83pub trait OpenSnapshotMptTrait<'db> {
84 type SnapshotDbBorrowSharedType: 'db + SnapshotMptTraitRead;
85 type SnapshotDbBorrowMutType: 'db + SnapshotMptTraitRw;
86 type SnapshotDbAsOwnedType: 'db + SnapshotMptTraitRw;
87
88 fn open_snapshot_mpt_owned(
89 &'db mut self,
90 ) -> StorageResult<Self::SnapshotDbBorrowMutType>;
91
92 fn open_snapshot_mpt_as_owned(
93 &'db self,
94 ) -> StorageResult<Self::SnapshotDbAsOwnedType>;
95
96 fn open_snapshot_mpt_shared(
97 &'db self,
98 ) -> StorageResult<Self::SnapshotDbBorrowSharedType>;
99}
100
101pub trait SnapshotDbTrait:
102 KeyValueDbTraitOwnedRead
103 + KeyValueDbTraitRead
104 + KeyValueDbTraitSingleWriter
105 + for<'db> OpenSnapshotMptTrait<'db>
106 + Sized
107{
108 type SnapshotKvdbIterTraitTag;
109
110 type SnapshotKvdbIterType: WrappedTrait<
111 dyn KeyValueDbIterableTrait<
112 MptKeyValue,
113 [u8],
114 Self::SnapshotKvdbIterTraitTag,
115 >,
116 >;
117
118 fn get_null_snapshot() -> Self;
119
120 fn open(
124 snapshot_path: &Path, readonly: bool,
125 already_open_snapshots: &AlreadyOpenSnapshots<Self>,
126 open_semaphore: &Arc<Semaphore>,
127 ) -> StorageResult<Self>;
128
129 fn create(
133 snapshot_path: &Path,
134 already_open_snapshots: &AlreadyOpenSnapshots<Self>,
135 open_semaphore: &Arc<Semaphore>, mpt_table_in_current_db: bool,
136 ) -> StorageResult<Self>;
137
138 fn direct_merge(
139 &mut self, old_snapshot_db: Option<&Arc<Self>>,
140 mpt_snapshot: &mut Option<SnapshotMptDbSqlite>,
141 recover_mpt_with_kv_snapshot_exist: bool,
142 in_reconstruct_snapshot_state: bool,
143 ) -> StorageResult<MerkleHash>;
144
145 fn copy_and_merge(
146 &mut self, old_snapshot_db: &Arc<Self>,
147 mpt_snapshot_db: &mut Option<SnapshotMptDbSqlite>,
148 in_reconstruct_snapshot_state: bool,
149 ) -> StorageResult<MerkleHash>;
150
151 fn start_transaction(&mut self) -> StorageResult<()>;
152
153 fn commit_transaction(&mut self) -> StorageResult<()>;
154
155 fn is_mpt_table_in_current_db(&self) -> bool;
156
157 fn snapshot_kv_iterator(
158 &self,
159 ) -> StorageResult<
160 Wrap<
161 '_,
162 Self::SnapshotKvdbIterType,
163 dyn KeyValueDbIterableTrait<
164 MptKeyValue,
165 [u8],
166 Self::SnapshotKvdbIterTraitTag,
167 >,
168 >,
169 >;
170}
171
172use crate::{
173 impls::{
174 errors::Result as StorageResult,
175 storage_db::{
176 snapshot_db_manager_sqlite::AlreadyOpenSnapshots,
177 snapshot_mpt_db_sqlite::SnapshotMptDbSqlite,
178 },
179 },
180 storage_db::{
181 KeyValueDbIterableTrait, KeyValueDbTraitOwnedRead, KeyValueDbTraitRead,
182 KeyValueDbTraitSingleWriter, SnapshotMptTraitRead, SnapshotMptTraitRw,
183 },
184 utils::wrap::{Wrap, WrappedTrait},
185 MptKeyValue,
186};
187use derive_more::Debug;
188use malloc_size_of_derive::MallocSizeOf as DeriveMallocSizeOf;
189use primitives::{EpochId, MerkleHash, MERKLE_NULL_NODE, NULL_EPOCH};
190use rlp::{Decodable, DecoderError, Encodable, Rlp, RlpStream};
191use rlp_derive::{RlpDecodable, RlpEncodable};
192use std::{path::Path, sync::Arc};
193use tokio::sync::Semaphore;