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