fuel_core/database/
database_description.rs1use core::fmt::Debug;
2use fuel_core_storage::kv_store::StorageColumn;
3use fuel_core_types::{
4 blockchain::primitives::DaBlockHeight,
5 fuel_types::BlockHeight,
6};
7use std::collections::HashSet;
8use strum::IntoEnumIterator;
9
10pub mod compression;
11pub mod gas_price;
12pub mod off_chain;
13pub mod on_chain;
14pub mod relayer;
15
16#[cfg(feature = "rpc")]
17pub mod block_aggregator;
18
19pub trait DatabaseHeight: PartialEq + Default + Debug + Copy + Send + Sync {
20 fn as_u64(&self) -> u64;
21
22 fn advance_height(&self) -> Option<Self>;
23
24 fn rollback_height(&self) -> Option<Self>;
25}
26
27impl DatabaseHeight for BlockHeight {
28 fn as_u64(&self) -> u64 {
29 let height: u32 = (*self).into();
30 height as u64
31 }
32
33 fn advance_height(&self) -> Option<Self> {
34 self.succ()
35 }
36
37 fn rollback_height(&self) -> Option<Self> {
38 self.pred()
39 }
40}
41
42impl DatabaseHeight for DaBlockHeight {
43 fn as_u64(&self) -> u64 {
44 self.0
45 }
46
47 fn advance_height(&self) -> Option<Self> {
48 self.0.checked_add(1).map(Into::into)
49 }
50
51 fn rollback_height(&self) -> Option<Self> {
52 self.0.checked_sub(1).map(Into::into)
53 }
54}
55
56pub trait DatabaseDescription: 'static + Copy + Debug + Send + Sync {
58 type Column: StorageColumn + strum::EnumCount + enum_iterator::Sequence;
60 type Height: DatabaseHeight;
62
63 fn version() -> u32;
65
66 fn name() -> String;
68
69 fn metadata_column() -> Self::Column;
71
72 fn prefix(column: &Self::Column) -> Option<usize>;
74}
75
76#[derive(
77 Copy,
78 Clone,
79 Debug,
80 serde::Serialize,
81 serde::Deserialize,
82 Eq,
83 PartialEq,
84 Hash,
85 strum::EnumIter,
86)]
87pub enum IndexationKind {
88 Balances,
89 CoinsToSpend,
90 AssetMetadata,
91}
92
93impl IndexationKind {
94 pub fn all() -> impl Iterator<Item = Self> {
95 Self::iter()
96 }
97}
98
99#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
101pub enum DatabaseMetadata<Height> {
102 V1 {
103 version: u32,
104 height: Height,
105 },
106 V2 {
107 version: u32,
108 height: Height,
109 indexation_availability: HashSet<IndexationKind>,
110 },
111}
112
113impl<Height> DatabaseMetadata<Height> {
114 pub fn version(&self) -> u32 {
116 match self {
117 Self::V1 { version, .. } => *version,
118 Self::V2 { version, .. } => *version,
119 }
120 }
121
122 pub fn height(&self) -> &Height {
124 match self {
125 Self::V1 { height, .. } => height,
126 Self::V2 { height, .. } => height,
127 }
128 }
129
130 pub fn indexation_available(&self, kind: IndexationKind) -> bool {
132 match self {
133 Self::V1 { .. } => false,
134 Self::V2 {
135 indexation_availability,
136 ..
137 } => indexation_availability.contains(&kind),
138 }
139 }
140}
141
142pub fn indexation_availability<D>(
144 metadata: Option<DatabaseMetadata<D::Height>>,
145) -> HashSet<IndexationKind>
146where
147 D: DatabaseDescription,
148{
149 match metadata {
150 Some(DatabaseMetadata::V1 { .. }) => HashSet::new(),
151 Some(DatabaseMetadata::V2 {
152 indexation_availability,
153 ..
154 }) => indexation_availability.clone(),
155 None => IndexationKind::all().collect(),
158 }
159}