kaspa_consensus/consensus/
storage.rs1use crate::{
2 config::Config,
3 model::stores::{
4 acceptance_data::DbAcceptanceDataStore,
5 block_transactions::DbBlockTransactionsStore,
6 block_window_cache::BlockWindowCacheStore,
7 daa::DbDaaStore,
8 depth::DbDepthStore,
9 ghostdag::{CompactGhostdagData, DbGhostdagStore},
10 headers::{CompactHeaderData, DbHeadersStore},
11 headers_selected_tip::DbHeadersSelectedTipStore,
12 past_pruning_points::DbPastPruningPointsStore,
13 pruning::DbPruningStore,
14 pruning_utxoset::PruningUtxosetStores,
15 reachability::{DbReachabilityStore, ReachabilityData},
16 relations::DbRelationsStore,
17 selected_chain::DbSelectedChainStore,
18 statuses::DbStatusesStore,
19 tips::DbTipsStore,
20 utxo_diffs::DbUtxoDiffsStore,
21 utxo_multisets::DbUtxoMultisetsStore,
22 virtual_state::{LkgVirtualState, VirtualStores},
23 DB,
24 },
25 processes::{ghostdag::ordering::SortableBlock, reachability::inquirer as reachability, relations},
26};
27
28use super::cache_policy_builder::CachePolicyBuilder as PolicyBuilder;
29use itertools::Itertools;
30use kaspa_consensus_core::{blockstatus::BlockStatus, BlockHashSet};
31use kaspa_database::registry::DatabaseStorePrefixes;
32use kaspa_hashes::Hash;
33use parking_lot::RwLock;
34use std::{ops::DerefMut, sync::Arc};
35
36pub struct ConsensusStorage {
37 db: Arc<DB>,
39
40 pub statuses_store: Arc<RwLock<DbStatusesStore>>,
42 pub relations_stores: Arc<RwLock<Vec<DbRelationsStore>>>,
43 pub reachability_store: Arc<RwLock<DbReachabilityStore>>,
44 pub reachability_relations_store: Arc<RwLock<DbRelationsStore>>,
45 pub pruning_point_store: Arc<RwLock<DbPruningStore>>,
46 pub headers_selected_tip_store: Arc<RwLock<DbHeadersSelectedTipStore>>,
47 pub body_tips_store: Arc<RwLock<DbTipsStore>>,
48 pub pruning_utxoset_stores: Arc<RwLock<PruningUtxosetStores>>,
49 pub virtual_stores: Arc<RwLock<VirtualStores>>,
50 pub selected_chain_store: Arc<RwLock<DbSelectedChainStore>>,
51
52 pub ghostdag_stores: Arc<Vec<Arc<DbGhostdagStore>>>,
54 pub ghostdag_primary_store: Arc<DbGhostdagStore>,
55 pub headers_store: Arc<DbHeadersStore>,
56 pub block_transactions_store: Arc<DbBlockTransactionsStore>,
57 pub past_pruning_points_store: Arc<DbPastPruningPointsStore>,
58 pub daa_excluded_store: Arc<DbDaaStore>,
59 pub depth_store: Arc<DbDepthStore>,
60
61 pub utxo_diffs_store: Arc<DbUtxoDiffsStore>,
63 pub utxo_multisets_store: Arc<DbUtxoMultisetsStore>,
64 pub acceptance_data_store: Arc<DbAcceptanceDataStore>,
65
66 pub block_window_cache_for_difficulty: Arc<BlockWindowCacheStore>,
68 pub block_window_cache_for_past_median_time: Arc<BlockWindowCacheStore>,
69
70 pub lkg_virtual_state: LkgVirtualState,
74}
75
76impl ConsensusStorage {
77 pub fn new(db: Arc<DB>, config: Arc<Config>) -> Arc<Self> {
78 let scale_factor = config.ram_scale;
79 let scaled = |s| (s as f64 * scale_factor) as usize;
80
81 let params = &config.params;
82 let perf_params = &config.perf;
83
84 let pruning_depth = params.pruning_depth as usize;
86 let pruning_size_for_caches = (params.pruning_depth + params.finality_depth) as usize; let level_lower_bound = 2 * params.pruning_proof_m as usize; let daa_excluded_budget = scaled(30_000_000);
91 let statuses_budget = scaled(30_000_000);
92 let reachability_data_budget = scaled(20_000_000);
93 let reachability_sets_budget = scaled(20_000_000); let ghostdag_compact_budget = scaled(15_000_000);
95 let headers_compact_budget = scaled(5_000_000);
96 let parents_budget = scaled(40_000_000); let children_budget = scaled(5_000_000); let ghostdag_budget = scaled(80_000_000); let headers_budget = scaled(80_000_000);
100 let transactions_budget = scaled(40_000_000);
101 let utxo_diffs_budget = scaled(40_000_000);
102 let block_window_budget = scaled(200_000_000); let acceptance_data_budget = scaled(40_000_000);
104
105 let daa_excluded_bytes = size_of::<Hash>() + size_of::<BlockHashSet>(); let status_bytes = size_of::<Hash>() + size_of::<BlockStatus>();
108 let reachability_data_bytes = size_of::<Hash>() + size_of::<ReachabilityData>();
109 let ghostdag_compact_bytes = size_of::<Hash>() + size_of::<CompactGhostdagData>();
110 let headers_compact_bytes = size_of::<Hash>() + size_of::<CompactHeaderData>();
111 let difficulty_window_bytes = params.difficulty_window_size(0) * size_of::<SortableBlock>();
112 let median_window_bytes = params.past_median_time_window_size(0) * size_of::<SortableBlock>();
113
114 let daa_excluded_builder =
116 PolicyBuilder::new().max_items(pruning_depth).bytes_budget(daa_excluded_budget).unit_bytes(daa_excluded_bytes).untracked(); let statuses_builder =
118 PolicyBuilder::new().max_items(pruning_size_for_caches).bytes_budget(statuses_budget).unit_bytes(status_bytes).untracked();
119 let reachability_data_builder = PolicyBuilder::new()
120 .max_items(pruning_size_for_caches)
121 .bytes_budget(reachability_data_budget)
122 .unit_bytes(reachability_data_bytes)
123 .untracked();
124 let ghostdag_compact_builder = PolicyBuilder::new()
125 .max_items(pruning_size_for_caches)
126 .bytes_budget(ghostdag_compact_budget)
127 .unit_bytes(ghostdag_compact_bytes)
128 .min_items(level_lower_bound)
129 .untracked();
130 let headers_compact_builder = PolicyBuilder::new()
131 .max_items(pruning_size_for_caches)
132 .bytes_budget(headers_compact_budget)
133 .unit_bytes(headers_compact_bytes)
134 .untracked();
135 let parents_builder = PolicyBuilder::new()
136 .bytes_budget(parents_budget)
137 .unit_bytes(size_of::<Hash>())
138 .min_items(level_lower_bound)
139 .tracked_units();
140 let children_builder = PolicyBuilder::new()
141 .bytes_budget(children_budget)
142 .unit_bytes(size_of::<Hash>())
143 .min_items(level_lower_bound)
144 .tracked_units();
145 let reachability_sets_builder =
146 PolicyBuilder::new().bytes_budget(reachability_sets_budget).unit_bytes(size_of::<Hash>()).tracked_units();
147 let difficulty_window_builder = PolicyBuilder::new()
148 .max_items(perf_params.block_window_cache_size)
149 .bytes_budget(block_window_budget)
150 .unit_bytes(difficulty_window_bytes)
151 .untracked();
152 let median_window_builder = PolicyBuilder::new()
153 .max_items(perf_params.block_window_cache_size)
154 .bytes_budget(block_window_budget)
155 .unit_bytes(median_window_bytes)
156 .untracked();
157 let ghostdag_builder = PolicyBuilder::new().bytes_budget(ghostdag_budget).min_items(level_lower_bound).tracked_bytes();
158 let headers_builder = PolicyBuilder::new().bytes_budget(headers_budget).tracked_bytes();
159 let utxo_diffs_builder = PolicyBuilder::new().bytes_budget(utxo_diffs_budget).tracked_bytes();
160 let block_data_builder = PolicyBuilder::new().max_items(perf_params.block_data_cache_size).untracked();
161 let header_data_builder = PolicyBuilder::new().max_items(perf_params.header_data_cache_size).untracked();
162 let utxo_set_builder = PolicyBuilder::new().max_items(perf_params.utxo_set_cache_size).untracked();
163 let transactions_builder = PolicyBuilder::new().bytes_budget(transactions_budget).tracked_bytes();
164 let acceptance_data_builder = PolicyBuilder::new().bytes_budget(acceptance_data_budget).tracked_bytes();
165 let past_pruning_points_builder = PolicyBuilder::new().max_items(1024).untracked();
166
167 let statuses_store = Arc::new(RwLock::new(DbStatusesStore::new(db.clone(), statuses_builder.build())));
171 let relations_stores = Arc::new(RwLock::new(
172 (0..=params.max_block_level)
173 .map(|level| {
174 DbRelationsStore::new(
175 db.clone(),
176 level,
177 parents_builder.downscale(level).build(),
178 children_builder.downscale(level).build(),
179 )
180 })
181 .collect_vec(),
182 ));
183 let reachability_store = Arc::new(RwLock::new(DbReachabilityStore::new(
184 db.clone(),
185 reachability_data_builder.build(),
186 reachability_sets_builder.build(),
187 )));
188
189 let reachability_relations_store = Arc::new(RwLock::new(DbRelationsStore::with_prefix(
190 db.clone(),
191 DatabaseStorePrefixes::ReachabilityRelations.as_ref(),
192 parents_builder.build(),
193 children_builder.build(),
194 )));
195
196 let ghostdag_stores = Arc::new(
197 (0..=params.max_block_level)
198 .map(|level| {
199 Arc::new(DbGhostdagStore::new(
200 db.clone(),
201 level,
202 ghostdag_builder.downscale(level).build(),
203 ghostdag_compact_builder.downscale(level).build(),
204 ))
205 })
206 .collect_vec(),
207 );
208 let ghostdag_primary_store = ghostdag_stores[0].clone();
209 let daa_excluded_store = Arc::new(DbDaaStore::new(db.clone(), daa_excluded_builder.build()));
210 let headers_store = Arc::new(DbHeadersStore::new(db.clone(), headers_builder.build(), headers_compact_builder.build()));
211 let depth_store = Arc::new(DbDepthStore::new(db.clone(), header_data_builder.build()));
212 let selected_chain_store = Arc::new(RwLock::new(DbSelectedChainStore::new(db.clone(), header_data_builder.build())));
213
214 let pruning_point_store = Arc::new(RwLock::new(DbPruningStore::new(db.clone())));
216 let past_pruning_points_store = Arc::new(DbPastPruningPointsStore::new(db.clone(), past_pruning_points_builder.build()));
217 let pruning_utxoset_stores = Arc::new(RwLock::new(PruningUtxosetStores::new(db.clone(), utxo_set_builder.build())));
218
219 let block_transactions_store = Arc::new(DbBlockTransactionsStore::new(db.clone(), transactions_builder.build()));
221 let utxo_diffs_store = Arc::new(DbUtxoDiffsStore::new(db.clone(), utxo_diffs_builder.build()));
222 let utxo_multisets_store = Arc::new(DbUtxoMultisetsStore::new(db.clone(), block_data_builder.build()));
223 let acceptance_data_store = Arc::new(DbAcceptanceDataStore::new(db.clone(), acceptance_data_builder.build()));
224
225 let headers_selected_tip_store = Arc::new(RwLock::new(DbHeadersSelectedTipStore::new(db.clone())));
227 let body_tips_store = Arc::new(RwLock::new(DbTipsStore::new(db.clone())));
228
229 let block_window_cache_for_difficulty = Arc::new(BlockWindowCacheStore::new(difficulty_window_builder.build()));
231 let block_window_cache_for_past_median_time = Arc::new(BlockWindowCacheStore::new(median_window_builder.build()));
232
233 let lkg_virtual_state = LkgVirtualState::default();
235 let virtual_stores =
236 Arc::new(RwLock::new(VirtualStores::new(db.clone(), lkg_virtual_state.clone(), utxo_set_builder.build())));
237
238 reachability::init(reachability_store.write().deref_mut()).unwrap();
240 relations::init(reachability_relations_store.write().deref_mut());
241
242 Arc::new(Self {
243 db,
244 statuses_store,
245 relations_stores,
246 reachability_relations_store,
247 reachability_store,
248 ghostdag_stores,
249 ghostdag_primary_store,
250 pruning_point_store,
251 headers_selected_tip_store,
252 body_tips_store,
253 headers_store,
254 block_transactions_store,
255 pruning_utxoset_stores,
256 virtual_stores,
257 selected_chain_store,
258 acceptance_data_store,
259 past_pruning_points_store,
260 daa_excluded_store,
261 depth_store,
262 utxo_diffs_store,
263 utxo_multisets_store,
264 block_window_cache_for_difficulty,
265 block_window_cache_for_past_median_time,
266 lkg_virtual_state,
267 })
268 }
269}