1#![allow(clippy::mut_from_ref)]
7
8#[macro_use]
9extern crate cfx_util_macros;
10#[macro_use]
11extern crate lazy_static;
12#[macro_use]
13extern crate log;
14
15#[macro_use]
16pub mod utils;
17
18pub(self) mod snapshot_manager;
19pub mod state;
20pub mod state_manager;
21#[macro_use]
22pub mod storage_db;
23
24pub mod tests;
25
26mod impls;
27
28pub mod storage_dir {
29 use std::path::PathBuf;
30 lazy_static! {
31 pub static ref DELTA_MPTS_DIR: PathBuf =
32 ["storage_db", "delta_mpts"].iter().collect::<PathBuf>();
33 pub static ref SNAPSHOT_DIR: PathBuf =
34 ["storage_db", "snapshot"].iter().collect::<PathBuf>();
35 pub static ref SNAPSHOT_INFO_DB_NAME: &'static str = "snapshot_info";
36 pub static ref SNAPSHOT_INFO_DB_PATH: PathBuf =
37 ["storage_db", "snapshot_info_db"]
38 .iter()
39 .collect::<PathBuf>();
40 pub static ref STORAGE_DIR: PathBuf = "storage_db".into();
41 }
42}
43
44#[derive(Debug, Clone)]
46pub struct ConsensusParam {
47 pub snapshot_epoch_count: u32,
53
54 pub era_epoch_count: u64,
55}
56
57#[derive(Debug, Clone, Eq, PartialEq)]
58pub enum ProvideExtraSnapshotSyncConfig {
59 StableCheckpoint,
64 EpochNearestMultipleOf(u32),
65}
66
67impl ProvideExtraSnapshotSyncConfig {
68 pub fn from_str(config: &str) -> Option<Self> {
69 const MULTIPLE_OF_PREFIX: &'static str = "multiple_of_";
70 if config == "checkpoint" {
71 Some(Self::StableCheckpoint)
72 } else if config.starts_with(MULTIPLE_OF_PREFIX) {
73 let number_str = &config[MULTIPLE_OF_PREFIX.len()..];
74 match number_str.parse::<u32>() {
75 Err(_) => None,
76 Ok(num) => Some(Self::EpochNearestMultipleOf(num)),
77 }
78 } else {
79 None
80 }
81 }
82
83 pub fn parse_config_list(
84 config: &str,
85 ) -> std::result::Result<Vec<Self>, String> {
86 let mut list = vec![];
87 for item in config.split(",") {
88 if item.len() > 0 {
89 list.push(Self::from_str(item).ok_or_else(|| {
90 format!(
91 "{} is not a valid ProvideExtraSnapshotSyncConfig",
92 item
93 )
94 })?);
95 }
96 }
97 Ok(list)
98 }
99}
100
101#[derive(Debug, Clone)]
102pub struct StorageConfiguration {
103 pub additional_maintained_snapshot_count: u32,
104 pub consensus_param: ConsensusParam,
105 pub debug_snapshot_checker_threads: u16,
106 pub delta_mpts_cache_recent_lfu_factor: f64,
107 pub delta_mpts_cache_start_size: u32,
108 pub delta_mpts_cache_size: u32,
109 pub delta_mpts_node_map_vec_size: u32,
110 pub delta_mpts_slab_idle_size: u32,
111 pub single_mpt_cache_start_size: u32,
112 pub single_mpt_cache_size: u32,
113 pub single_mpt_slab_idle_size: u32,
114 pub max_open_snapshots: u16,
115 pub path_delta_mpts_dir: PathBuf,
116 pub path_storage_dir: PathBuf,
117 pub path_snapshot_dir: PathBuf,
118 pub path_snapshot_info_db: PathBuf,
119 pub provide_more_snapshot_for_sync: Vec<ProvideExtraSnapshotSyncConfig>,
120 pub max_open_mpt_count: u32,
121 pub enable_single_mpt_storage: bool,
122 pub single_mpt_space: Option<Space>,
123 pub cip90a: u64,
124 pub keep_snapshot_before_stable_checkpoint: bool,
125 pub use_isolated_db_for_mpt_table: bool,
126 pub use_isolated_db_for_mpt_table_height: Option<u64>,
127 pub keep_era_genesis_snapshot: bool,
128 pub backup_mpt_snapshot: bool,
129}
130
131impl StorageConfiguration {
132 pub fn new_default(
133 conflux_data_dir: &str, snapshot_epoch_count: u32, era_epoch_count: u64,
134 ) -> Self {
135 let conflux_data_path = Path::new(conflux_data_dir);
136 StorageConfiguration {
137 additional_maintained_snapshot_count: 0,
138 consensus_param: ConsensusParam {
139 snapshot_epoch_count,
140 era_epoch_count,
141 },
142 debug_snapshot_checker_threads:
143 defaults::DEFAULT_DEBUG_SNAPSHOT_CHECKER_THREADS,
144 delta_mpts_cache_recent_lfu_factor:
145 defaults::DEFAULT_DELTA_MPTS_CACHE_RECENT_LFU_FACTOR,
146 delta_mpts_cache_size: defaults::DEFAULT_DELTA_MPTS_CACHE_SIZE,
147 delta_mpts_cache_start_size:
148 defaults::DEFAULT_DELTA_MPTS_CACHE_START_SIZE,
149 delta_mpts_node_map_vec_size: defaults::DEFAULT_NODE_MAP_SIZE,
150 delta_mpts_slab_idle_size:
151 defaults::DEFAULT_DELTA_MPTS_SLAB_IDLE_SIZE,
152 single_mpt_cache_start_size:
153 defaults::DEFAULT_DELTA_MPTS_CACHE_START_SIZE * 2,
154 single_mpt_cache_size: defaults::DEFAULT_DELTA_MPTS_CACHE_SIZE * 2,
155 single_mpt_slab_idle_size:
156 defaults::DEFAULT_DELTA_MPTS_SLAB_IDLE_SIZE * 2,
157 max_open_snapshots: defaults::DEFAULT_MAX_OPEN_SNAPSHOTS,
158 path_delta_mpts_dir: conflux_data_path
159 .join(&*storage_dir::DELTA_MPTS_DIR),
160 path_snapshot_dir: conflux_data_path
161 .join(&*storage_dir::SNAPSHOT_DIR),
162 path_snapshot_info_db: conflux_data_path
163 .join(&*storage_dir::SNAPSHOT_INFO_DB_PATH),
164 path_storage_dir: conflux_data_path
165 .join(&*storage_dir::STORAGE_DIR),
166 provide_more_snapshot_for_sync: vec![
167 ProvideExtraSnapshotSyncConfig::StableCheckpoint,
168 ],
169 max_open_mpt_count: defaults::DEFAULT_MAX_OPEN_MPT,
170 enable_single_mpt_storage: false,
171 single_mpt_space: None,
172 cip90a: 0,
173 keep_snapshot_before_stable_checkpoint: true,
174 use_isolated_db_for_mpt_table: false,
175 use_isolated_db_for_mpt_table_height: None,
176 keep_era_genesis_snapshot: false,
177 backup_mpt_snapshot: true,
178 }
179 }
180
181 pub fn full_state_start_height(&self) -> Option<u64> {
182 if self.enable_single_mpt_storage {
183 let height = if self.single_mpt_space == Some(Space::Ethereum) {
184 self.cip90a
187 } else {
188 0
189 };
190 Some(height)
191 } else {
192 None
193 }
194 }
195}
196
197pub use self::{
198 impls::{
199 defaults,
200 delta_mpt::*,
201 errors::{Error, Result},
202 merkle_patricia_trie::{
203 mpt_cursor::rlp_key_value_len, simple_mpt::*,
204 trie_proof::TrieProofNode, CompressedPathRaw, KVInserter,
205 MptKeyValue, TrieProof, VanillaChildrenTable,
206 },
207 node_merkle_proof::{NodeMerkleProof, StorageRootProof},
208 proof_merger::StateProofMerger,
209 recording_storage::RecordingStorage,
210 snapshot_sync::{FullSyncVerifier, MptSlicer},
211 state_proof::StateProof,
212 storage_db::{
213 kvdb_rocksdb::KvdbRocksdb,
214 kvdb_sqlite::{KvdbSqlite, KvdbSqliteStatements},
215 kvdb_sqlite_sharded::KvdbSqliteSharded,
216 snapshot_db_manager_sqlite::SnapshotDbManagerSqlite,
217 sqlite::SqliteConnection,
218 },
219 },
220 replicated_state::ReplicatedState,
221 state::{
222 State as StorageState, StateTrait as StorageStateTrait,
223 StateTraitExt as StorageStateTraitExt,
224 },
225 state_manager::{
226 StateIndex, StateManager as StorageManager,
227 StateManagerTrait as StorageManagerTrait,
228 },
229 storage_db::{KeyValueDbIterableTrait, KeyValueDbTrait},
230};
231
232#[cfg(any(test, feature = "testonly_code"))]
233pub use self::tests::new_state_manager_for_unit_test as new_storage_manager_for_testing;
234use crate::impls::replicated_state;
235use cfx_internal_common::StateRootWithAuxInfo;
236use cfx_types::Space;
237use std::path::{Path, PathBuf};