Skip to main content

tycho_core/storage/
config.rs

1use std::num::NonZeroU32;
2use std::time::Duration;
3
4use bytesize::ByteSize;
5use serde::{Deserialize, Serialize};
6use tycho_util::config::PartialConfig;
7use tycho_util::serde_helpers;
8
9#[derive(Debug, Clone, Serialize, Deserialize, PartialConfig)]
10#[serde(deny_unknown_fields, default)]
11pub struct CoreStorageConfig {
12    /// Runtime cells cache size.
13    ///
14    /// Default: 256 MB.
15    #[important]
16    pub cells_cache_size: ByteSize,
17
18    /// Minimal epoch interval when the state can be reused.
19    ///
20    /// Default: 3.
21    pub drop_interval: u32,
22
23    /// Whether to pack blocks into archives.
24    ///
25    /// Default: `true`.
26    pub store_archives: bool,
27
28    /// Number of virtual shards.
29    ///
30    /// Default: `5` (= 32 virtual shards).
31    pub shard_split_depth: u8,
32
33    /// Store every Nth shard state to storage
34    ///
35    /// Default: 5
36    pub store_shard_state_step: NonZeroU32,
37
38    /// Maximum number of accumulated new cells before forcing state storage.
39    /// Prevents large state diffs that take too long to save.
40    ///
41    /// Default: `500_000` cells
42    pub max_new_cells_threshold: usize,
43
44    /// Archives storage config.
45    ///
46    /// Archives are disabled if this field is `None`.
47    pub archives_gc: Option<ArchivesGcConfig>,
48
49    /// States GC config.
50    ///
51    /// States GC is disabled if this field is `None`.
52    pub states_gc: Option<StatesGcConfig>,
53
54    /// Blocks GC config.
55    ///
56    /// Blocks GC is disabled if this field is `None`.
57    pub blocks_gc: Option<BlocksGcConfig>,
58
59    /// Blocks cache config.
60    pub blocks_cache: BlocksCacheConfig,
61
62    /// Blob DB config.
63    pub blob_db: BlobDbConfig,
64}
65
66impl CoreStorageConfig {
67    #[cfg(any(test, feature = "test"))]
68    pub fn new_potato() -> Self {
69        Self {
70            cells_cache_size: ByteSize::kb(1024),
71            blob_db: BlobDbConfig {
72                pre_create_cas_tree: false,
73            },
74            archives_gc: None,
75            states_gc: None,
76            blocks_gc: None,
77            ..Default::default()
78        }
79    }
80
81    pub fn without_gc(mut self) -> Self {
82        self.archives_gc = None;
83        self.states_gc = None;
84        self.blocks_gc = None;
85        self
86    }
87}
88
89impl Default for CoreStorageConfig {
90    fn default() -> Self {
91        Self {
92            cells_cache_size: ByteSize::mb(256),
93            drop_interval: 3,
94            store_archives: true,
95            shard_split_depth: 5,
96            store_shard_state_step: NonZeroU32::new(5).unwrap(),
97            max_new_cells_threshold: 500_000,
98            archives_gc: Some(ArchivesGcConfig::default()),
99            states_gc: Some(StatesGcConfig::default()),
100            blocks_gc: Some(BlocksGcConfig::default()),
101            blocks_cache: BlocksCacheConfig::default(),
102            blob_db: BlobDbConfig::default(),
103        }
104    }
105}
106
107#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
108#[serde(default, deny_unknown_fields)]
109pub struct ArchivesGcConfig {
110    /// Remove archives after this interval after the new persistent state
111    #[serde(with = "serde_helpers::humantime")]
112    pub persistent_state_offset: Duration,
113}
114
115impl Default for ArchivesGcConfig {
116    fn default() -> Self {
117        Self {
118            persistent_state_offset: Duration::from_secs(300),
119        }
120    }
121}
122
123#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
124#[serde(default, deny_unknown_fields)]
125pub struct StatesGcConfig {
126    /// Wether to add random offset to the first interval.
127    ///
128    /// Default: true.
129    pub random_offset: bool,
130    /// Default: 900
131    #[serde(with = "serde_helpers::humantime")]
132    pub interval: Duration,
133}
134
135impl Default for StatesGcConfig {
136    fn default() -> Self {
137        Self {
138            random_offset: true,
139            interval: Duration::from_secs(60),
140        }
141    }
142}
143
144#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
145#[serde(default)]
146pub struct BlocksGcConfig {
147    /// Blocks GC type
148    /// - `before_previous_key_block` - on each new key block delete all blocks before the previous one
149    /// - `before_previous_persistent_state` - on each new key block delete all blocks before the
150    ///   previous key block with persistent state
151    #[serde(flatten)]
152    pub ty: BlocksGcType,
153
154    /// Whether to enable blocks GC during sync. Default: true
155    pub enable_for_sync: bool,
156
157    /// Max `WriteBatch` entries before apply
158    pub max_blocks_per_batch: Option<usize>,
159}
160
161impl Default for BlocksGcConfig {
162    fn default() -> Self {
163        Self {
164            ty: BlocksGcType::BeforeSafeDistance {
165                safe_distance: 1000,
166                min_interval: Duration::from_secs(60),
167            },
168            enable_for_sync: true,
169            max_blocks_per_batch: Some(100_000),
170        }
171    }
172}
173
174#[derive(Debug, Copy, Clone, Eq, PartialEq, Serialize, Deserialize)]
175#[serde(tag = "type")]
176pub enum BlocksGcType {
177    /// Remove all blocks before the specified safe distance (of mc blocks).
178    BeforeSafeDistance {
179        /// Number of masterchain blocks to keep.
180        safe_distance: u32,
181        /// Minimum interval between GC runs.
182        ///
183        /// Should be about 1 minute.
184        #[serde(with = "serde_helpers::humantime")]
185        min_interval: Duration,
186    },
187    /// Remove all blocks before the previous key block.
188    BeforePreviousKeyBlock,
189    /// Remove all blocks before the previous persistent state.
190    BeforePreviousPersistentState,
191}
192
193#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
194#[serde(default, deny_unknown_fields)]
195pub struct BlocksCacheConfig {
196    /// Entry TTL.
197    ///
198    /// Default: `5 min`.
199    #[serde(with = "serde_helpers::humantime")]
200    pub ttl: Duration,
201
202    /// Cache capacity in bytes.
203    ///
204    /// Default: `500 MB`.
205    pub size: ByteSize,
206}
207
208impl Default for BlocksCacheConfig {
209    fn default() -> Self {
210        Self {
211            ttl: Duration::from_secs(300),
212            size: ByteSize::mb(500),
213        }
214    }
215}
216
217#[derive(Debug, Clone, Serialize, Deserialize)]
218#[serde(default, deny_unknown_fields)]
219pub struct BlobDbConfig {
220    pub pre_create_cas_tree: bool,
221}
222
223impl Default for BlobDbConfig {
224    fn default() -> Self {
225        Self {
226            pre_create_cas_tree: true,
227        }
228    }
229}