fuel_core/database/
database_description.rsuse core::fmt::Debug;
use fuel_core_storage::kv_store::StorageColumn;
use fuel_core_types::{
blockchain::primitives::DaBlockHeight,
fuel_types::BlockHeight,
};
use std::collections::HashSet;
use strum::IntoEnumIterator;
pub mod gas_price;
pub mod off_chain;
pub mod on_chain;
pub mod relayer;
pub trait DatabaseHeight: PartialEq + Default + Debug + Copy + Send + Sync {
fn as_u64(&self) -> u64;
fn advance_height(&self) -> Option<Self>;
fn rollback_height(&self) -> Option<Self>;
}
impl DatabaseHeight for BlockHeight {
fn as_u64(&self) -> u64 {
let height: u32 = (*self).into();
height as u64
}
fn advance_height(&self) -> Option<Self> {
self.succ()
}
fn rollback_height(&self) -> Option<Self> {
self.pred()
}
}
impl DatabaseHeight for DaBlockHeight {
fn as_u64(&self) -> u64 {
self.0
}
fn advance_height(&self) -> Option<Self> {
self.0.checked_add(1).map(Into::into)
}
fn rollback_height(&self) -> Option<Self> {
self.0.checked_sub(1).map(Into::into)
}
}
pub trait DatabaseDescription: 'static + Copy + Debug + Send + Sync {
type Column: StorageColumn + strum::EnumCount + enum_iterator::Sequence;
type Height: DatabaseHeight;
fn version() -> u32;
fn name() -> String;
fn metadata_column() -> Self::Column;
fn prefix(column: &Self::Column) -> Option<usize>;
}
#[derive(
Copy,
Clone,
Debug,
serde::Serialize,
serde::Deserialize,
Eq,
PartialEq,
Hash,
strum::EnumIter,
)]
pub enum IndexationKind {
Balances,
CoinsToSpend,
AssetMetadata,
}
impl IndexationKind {
pub fn all() -> impl Iterator<Item = Self> {
Self::iter()
}
}
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
pub enum DatabaseMetadata<Height> {
V1 {
version: u32,
height: Height,
},
V2 {
version: u32,
height: Height,
indexation_availability: HashSet<IndexationKind>,
},
}
impl<Height> DatabaseMetadata<Height> {
pub fn version(&self) -> u32 {
match self {
Self::V1 { version, .. } => *version,
Self::V2 { version, .. } => *version,
}
}
pub fn height(&self) -> &Height {
match self {
Self::V1 { height, .. } => height,
Self::V2 { height, .. } => height,
}
}
pub fn indexation_available(&self, kind: IndexationKind) -> bool {
match self {
Self::V1 { .. } => false,
Self::V2 {
indexation_availability,
..
} => indexation_availability.contains(&kind),
}
}
}
pub fn indexation_availability<D>(
metadata: Option<DatabaseMetadata<D::Height>>,
) -> HashSet<IndexationKind>
where
D: DatabaseDescription,
{
match metadata {
Some(DatabaseMetadata::V1 { .. }) => HashSet::new(),
Some(DatabaseMetadata::V2 {
indexation_availability,
..
}) => indexation_availability.clone(),
None => IndexationKind::all().collect(),
}
}