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 ShardStateStorage, ShardStateStorageError, ShardStateStorageMetrics, StoreStateHint,
32 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 let shard_state_storage = ShardStateStorage::new(
85 cells_db.clone(),
86 block_handle_storage.clone(),
87 block_storage.clone(),
88 ctx.temp_files().clone(),
89 config.cells_cache_size,
90 config.drop_interval,
91 )?;
92 let persistent_state_storage = PersistentStateStorage::new(
93 cells_db.clone(),
94 ctx.files_dir(),
95 node_state_storage.clone(),
96 block_handle_storage.clone(),
97 block_storage.clone(),
98 shard_state_storage.clone(),
99 )?;
100
101 persistent_state_storage.preload().await?;
102
103 let gc = CoreStorageGc::new(
104 &node_state_storage,
105 block_handle_storage.clone(),
106 block_storage.clone(),
107 shard_state_storage.clone(),
108 persistent_state_storage.clone(),
109 &config,
110 );
111
112 Ok(Self {
113 inner: Arc::new(Inner {
114 ctx,
115 db,
116 config,
117 gc,
118 block_handle_storage,
119 block_storage,
120 shard_state_storage,
121 persistent_state_storage,
122 block_connection_storage,
123 node_state_storage,
124 }),
125 })
126 }
127
128 pub fn context(&self) -> &StorageContext {
129 &self.inner.ctx
130 }
131
132 pub fn db(&self) -> &CoreDb {
133 &self.inner.db
134 }
135
136 pub fn config(&self) -> &CoreStorageConfig {
137 &self.inner.config
138 }
139
140 pub fn persistent_state_storage(&self) -> &PersistentStateStorage {
141 &self.inner.persistent_state_storage
142 }
143
144 pub fn block_handle_storage(&self) -> &BlockHandleStorage {
145 &self.inner.block_handle_storage
146 }
147
148 pub fn block_storage(&self) -> &BlockStorage {
149 &self.inner.block_storage
150 }
151
152 pub fn block_connection_storage(&self) -> &BlockConnectionStorage {
153 &self.inner.block_connection_storage
154 }
155
156 pub fn shard_state_storage(&self) -> &ShardStateStorage {
157 &self.inner.shard_state_storage
158 }
159
160 pub fn node_state(&self) -> &NodeStateStorage {
161 &self.inner.node_state_storage
162 }
163
164 pub fn open_stats(&self) -> &OpenStats {
165 self.inner.block_storage.open_stats()
166 }
167
168 pub fn trigger_archives_gc(&self, trigger: ManualGcTrigger) {
169 self.inner.gc.trigger_archives_gc(trigger);
170 }
171
172 pub fn trigger_blocks_gc(&self, trigger: ManualGcTrigger) {
173 self.inner.gc.trigger_blocks_gc(trigger);
174 }
175
176 pub fn trigger_states_gc(&self, trigger: ManualGcTrigger) {
177 self.inner.gc.trigger_states_gc(trigger);
178 }
179
180 pub(crate) fn update_gc_state(&self, is_key_block: bool, block: &BlockStuff) {
181 self.inner.gc.handle_block(is_key_block, block);
182 }
183}
184
185struct Inner {
186 ctx: StorageContext,
187 db: CoreDb,
188 config: CoreStorageConfig,
189 gc: CoreStorageGc,
190
191 block_handle_storage: Arc<BlockHandleStorage>,
192 block_connection_storage: Arc<BlockConnectionStorage>,
193 block_storage: Arc<BlockStorage>,
194 shard_state_storage: Arc<ShardStateStorage>,
195 node_state_storage: Arc<NodeStateStorage>,
196 persistent_state_storage: PersistentStateStorage,
197}