1use std::sync::Arc;
2
3use anyhow::Result;
4use tycho_block_util::block::BlockStuff;
5use tycho_storage::StorageContext;
6use tycho_storage::kv::ApplyMigrations;
7
8pub use self::block::{
9 ArchiveId, BlockGcStats, BlockStorage, BlockStorageConfig, MaybeExistingHandle, OpenStats,
10 PackageEntryKey, PartialBlockId, StoreBlockResult,
11};
12pub use self::block_connection::{BlockConnection, BlockConnectionStorage};
13pub use self::block_handle::{
14 BlockFlags, BlockHandle, BlockHandleStorage, BlockMeta, HandleCreationStatus,
15 KeyBlocksDirection, LoadedBlockMeta, NewBlockMeta, WeakBlockHandle,
16};
17pub use self::config::{
18 ArchivesGcConfig, BlocksCacheConfig, BlocksGcConfig, BlocksGcType, CoreStorageConfig,
19 StatesGcConfig,
20};
21pub use self::db::{CellsDb, CoreDb, CoreDbExt, CoreTables};
22use self::gc::CoreStorageGc;
23pub use self::gc::ManualGcTrigger;
24pub use self::node_state::{NodeStateStorage, NodeSyncState};
25pub use self::persistent_state::{
26 BriefBocHeader, PersistentState, PersistentStateInfo, PersistentStateKind,
27 PersistentStateStorage, QueueDiffReader, QueueStateReader, QueueStateWriter, ShardStateReader,
28 ShardStateWriter,
29};
30pub use self::shard_state::{
31 BlockInfoForApply, InitiatedStoreState, LoadStateHint, ShardStateStorage,
32 ShardStateStorageMetrics, StateNotFound, StoreStateHint, split_shard_accounts,
33};
34
35pub mod tables;
36
37pub(crate) mod block;
38mod block_connection;
39mod block_handle;
40mod config;
41mod db;
42mod gc;
43mod node_state;
44mod persistent_state;
45mod shard_state;
46mod util;
47
48pub const CORE_DB_SUBDIR: &str = "core";
49pub const CELLS_DB_SUBDIR: &str = "cells";
50
51#[derive(Clone)]
52#[repr(transparent)]
53pub struct CoreStorage {
54 inner: Arc<Inner>,
55}
56
57impl CoreStorage {
58 pub async fn open(ctx: StorageContext, config: CoreStorageConfig) -> Result<Self> {
59 let db: CoreDb = ctx.open_preconfigured(CORE_DB_SUBDIR)?;
60 db.normalize_version()?;
61 db.apply_migrations().await?;
62
63 let cells_db: CellsDb = ctx.open_preconfigured(CELLS_DB_SUBDIR)?;
64 cells_db.normalize_version()?;
65 cells_db.apply_migrations().await?;
66
67 let node_state_storage = Arc::new(NodeStateStorage::new(db.clone()));
68
69 let blocks_storage_config = BlockStorageConfig {
70 blocks_cache: config.blocks_cache,
71 blobs_root: ctx.root_dir().path().join("blobs"),
72 blob_db_config: config.blob_db.clone(),
73 };
74 let block_handle_storage = Arc::new(BlockHandleStorage::new(db.clone()));
75 let block_connection_storage = Arc::new(BlockConnectionStorage::new(db.clone()));
76 let block_storage = BlockStorage::new(
77 db.clone(),
78 blocks_storage_config,
79 block_handle_storage.clone(),
80 block_connection_storage.clone(),
81 )
82 .await?;
83 let block_storage = Arc::new(block_storage);
84
85 let shard_state_storage = ShardStateStorage::new(
86 cells_db.clone(),
87 block_handle_storage.clone(),
88 block_storage.clone(),
89 block_connection_storage.clone(),
90 ctx.temp_files().clone(),
91 &config,
92 )?;
93 let persistent_state_storage = PersistentStateStorage::new(
94 cells_db.clone(),
95 ctx.files_dir(),
96 node_state_storage.clone(),
97 block_handle_storage.clone(),
98 block_storage.clone(),
99 shard_state_storage.clone(),
100 )?;
101
102 persistent_state_storage.preload().await?;
103
104 let gc = CoreStorageGc::new(
105 &node_state_storage,
106 block_handle_storage.clone(),
107 block_storage.clone(),
108 shard_state_storage.clone(),
109 persistent_state_storage.clone(),
110 &config,
111 );
112
113 Ok(Self {
114 inner: Arc::new(Inner {
115 ctx,
116 db,
117 config,
118 gc,
119 block_handle_storage,
120 block_storage,
121 shard_state_storage,
122 persistent_state_storage,
123 block_connection_storage,
124 node_state_storage,
125 }),
126 })
127 }
128
129 pub fn context(&self) -> &StorageContext {
130 &self.inner.ctx
131 }
132
133 pub fn db(&self) -> &CoreDb {
134 &self.inner.db
135 }
136
137 pub fn config(&self) -> &CoreStorageConfig {
138 &self.inner.config
139 }
140
141 pub fn persistent_state_storage(&self) -> &PersistentStateStorage {
142 &self.inner.persistent_state_storage
143 }
144
145 pub fn block_handle_storage(&self) -> &BlockHandleStorage {
146 &self.inner.block_handle_storage
147 }
148
149 pub fn block_storage(&self) -> &BlockStorage {
150 &self.inner.block_storage
151 }
152
153 pub fn block_connection_storage(&self) -> &BlockConnectionStorage {
154 &self.inner.block_connection_storage
155 }
156
157 pub fn shard_state_storage(&self) -> &Arc<ShardStateStorage> {
158 &self.inner.shard_state_storage
159 }
160
161 pub fn node_state(&self) -> &NodeStateStorage {
162 &self.inner.node_state_storage
163 }
164
165 pub fn open_stats(&self) -> &OpenStats {
166 self.inner.block_storage.open_stats()
167 }
168
169 pub fn trigger_archives_gc(&self, trigger: ManualGcTrigger) {
170 self.inner.gc.trigger_archives_gc(trigger);
171 }
172
173 pub fn trigger_blocks_gc(&self, trigger: ManualGcTrigger) {
174 self.inner.gc.trigger_blocks_gc(trigger);
175 }
176
177 pub fn trigger_states_gc(&self, trigger: ManualGcTrigger) {
178 self.inner.gc.trigger_states_gc(trigger);
179 }
180
181 pub(crate) fn update_gc_state(&self, is_key_block: bool, block: &BlockStuff) {
182 self.inner.gc.handle_block(is_key_block, block);
183 }
184}
185
186struct Inner {
187 ctx: StorageContext,
188 db: CoreDb,
189 config: CoreStorageConfig,
190 gc: CoreStorageGc,
191
192 block_handle_storage: Arc<BlockHandleStorage>,
193 block_connection_storage: Arc<BlockConnectionStorage>,
194 block_storage: Arc<BlockStorage>,
195 shard_state_storage: Arc<ShardStateStorage>,
196 node_state_storage: Arc<NodeStateStorage>,
197 persistent_state_storage: PersistentStateStorage,
198}