fuel_core/state/historical_rocksdb/
description.rs1use crate::database::database_description::DatabaseDescription;
2use fuel_core_storage::kv_store::StorageColumn;
3
4pub const HISTORY_COLUMN_ID: u32 = u32::MAX / 2;
5pub const HISTORY_V2_COLUMN_ID: u32 = HISTORY_COLUMN_ID + 1;
8
9#[derive(Debug, Copy, Clone, enum_iterator::Sequence)]
10pub enum Column<Description>
11where
12 Description: DatabaseDescription,
13{
14 OriginalColumn(Description::Column),
15 HistoricalDuplicateColumn(Description::Column),
16 HistoryColumn,
18 HistoryV2Column,
20}
21
22impl<Description> strum::EnumCount for Column<Description>
23where
24 Description: DatabaseDescription,
25{
26 const COUNT: usize = Description::Column::COUNT + Description::Column::COUNT + 2 ;
29}
30
31impl<Description> StorageColumn for Column<Description>
32where
33 Description: DatabaseDescription,
34{
35 fn name(&self) -> String {
36 match self {
37 Column::OriginalColumn(c) => c.name(),
38 Column::HistoricalDuplicateColumn(c) => {
39 format!("history_{}", c.name())
40 }
41 Column::HistoryColumn => "modifications_history".to_string(),
42 Column::HistoryV2Column => "modifications_history_v2".to_string(),
43 }
44 }
45
46 fn id(&self) -> u32 {
47 match self {
48 Column::OriginalColumn(c) => c.id(),
49 Column::HistoricalDuplicateColumn(c) => {
50 historical_duplicate_column_id(c.id())
51 }
52 Column::HistoryColumn => HISTORY_COLUMN_ID,
53 Column::HistoryV2Column => HISTORY_V2_COLUMN_ID,
54 }
55 }
56}
57
58pub fn historical_duplicate_column_id(id: u32) -> u32 {
59 HISTORY_COLUMN_ID.saturating_sub(1).saturating_sub(id)
60}
61
62#[derive(Debug, Copy, Clone)]
63pub struct Historical<Description> {
64 _maker: core::marker::PhantomData<Description>,
65}
66
67impl<Description> DatabaseDescription for Historical<Description>
68where
69 Description: DatabaseDescription,
70{
71 type Column = Column<Description>;
72 type Height = Description::Height;
73
74 fn version() -> u32 {
75 Description::version()
76 }
77
78 fn name() -> String {
79 Description::name()
80 }
81
82 fn metadata_column() -> Self::Column {
83 Column::OriginalColumn(Description::metadata_column())
84 }
85
86 fn prefix(column: &Self::Column) -> Option<usize> {
87 match column {
88 Column::OriginalColumn(c) => Description::prefix(c),
89 Column::HistoricalDuplicateColumn(c) => {
90 Some(Description::prefix(c).unwrap_or(0).saturating_add(8)) }
92 Column::HistoryColumn | Column::HistoryV2Column => Some(8),
93 }
94 }
95}
96
97#[cfg(test)]
98mod tests {
99 use super::*;
100 use crate::database::database_description::{
101 DatabaseDescription,
102 off_chain::OffChain,
103 on_chain::OnChain,
104 relayer::Relayer,
105 };
106 use strum::EnumCount;
107
108 #[test]
109 fn iteration_over_all_columns_on_chain() {
110 let variants = enum_iterator::all::<Column<OnChain>>().collect::<Vec<_>>();
111 let original = <OnChain as DatabaseDescription>::Column::COUNT;
112 let duplicated = <OnChain as DatabaseDescription>::Column::COUNT;
113 let history_modification_versions = 2;
114 let expected_count = original + duplicated + history_modification_versions;
115 assert_eq!(variants.len(), expected_count);
116 assert_eq!(<Column<OnChain> as EnumCount>::COUNT, expected_count);
117 }
118
119 #[test]
120 fn iteration_over_all_columns_off_chain() {
121 let variants = enum_iterator::all::<Column<OffChain>>().collect::<Vec<_>>();
122 let original = <OffChain as DatabaseDescription>::Column::COUNT;
123 let duplicated = <OffChain as DatabaseDescription>::Column::COUNT;
124 let history_modification_versions = 2;
125 let expected_count = original + duplicated + history_modification_versions;
126 assert_eq!(variants.len(), expected_count);
127 assert_eq!(<Column<OffChain> as EnumCount>::COUNT, expected_count);
128 }
129
130 #[test]
131 fn iteration_over_all_columns_relayer() {
132 let variants = enum_iterator::all::<Column<Relayer>>().collect::<Vec<_>>();
133 let original = <Relayer as DatabaseDescription>::Column::COUNT;
134 let duplicated = <Relayer as DatabaseDescription>::Column::COUNT;
135 let history_modification_versions = 2;
136 let expected_count = original + duplicated + history_modification_versions;
137 assert_eq!(variants.len(), expected_count);
138 assert_eq!(<Column<Relayer> as EnumCount>::COUNT, expected_count);
139 }
140}