1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
use crate::{
    database::{
        Column,
        Database,
    },
    model::BlockHeight,
    state::Error,
};
use fuel_chain_config::ChainConfig;

pub(crate) const DB_VERSION_KEY: &[u8] = b"version";
pub(crate) const CHAIN_NAME_KEY: &[u8] = b"chain_name";
pub(crate) const CHAIN_HEIGHT_KEY: &[u8] = b"chain_height";
pub(crate) const FINALIZED_DA_HEIGHT_KEY: &[u8] = b"finalized_da_height";
pub(crate) const LAST_PUBLISHED_BLOCK_HEIGHT_KEY: &[u8] = b"last_publish_block_height";

/// Can be used to perform migrations in the future.
pub(crate) const DB_VERSION: u32 = 0;

impl Database {
    pub fn init(&self, config: &ChainConfig) -> Result<(), Error> {
        // check only for one field if it initialized or not.
        self.insert(CHAIN_NAME_KEY, Column::Metadata, config.chain_name.clone())
            .and_then(|v: Option<String>| {
                if v.is_some() {
                    Err(Error::ChainAlreadyInitialized)
                } else {
                    Ok(())
                }
            })?;

        let chain_height = config
            .initial_state
            .as_ref()
            .and_then(|c| c.height)
            .unwrap_or_default();

        let _: Option<u32> = self.insert(DB_VERSION_KEY, Column::Metadata, DB_VERSION)?;
        let _: Option<BlockHeight> =
            self.insert(CHAIN_HEIGHT_KEY, Column::Metadata, chain_height)?;
        Ok(())
    }

    pub fn get_chain_name(&self) -> Result<Option<String>, Error> {
        self.get(CHAIN_NAME_KEY, Column::Metadata)
    }

    pub fn get_starting_chain_height(&self) -> Result<Option<BlockHeight>, Error> {
        self.get(CHAIN_HEIGHT_KEY, Column::Metadata)
    }
}