pos_ledger_db/system_store/mod.rs
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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0
// Copyright 2021 Conflux Foundation. All rights reserved.
// Conflux is free software and distributed under GNU General Public License.
// See http://www.gnu.org/licenses/
//! This file defines system store APIs that operates data not part of the Diem
//! core data structures but information with regard to system running status,
//! statistics, etc.
use crate::{
    change_set::ChangeSet, ledger_counters::LedgerCounters,
    schema::ledger_counters::LedgerCountersSchema,
};
use anyhow::Result;
use diem_logger::prelude::*;
use diem_types::transaction::Version;
use schemadb::DB;
use std::sync::Arc;
#[derive(Debug)]
pub(crate) struct SystemStore {
    db: Arc<DB>,
}
impl SystemStore {
    pub fn new(db: Arc<DB>) -> Self { Self { db } }
    /// Increase ledger counters.
    ///
    /// The base values are read out of db, to which the `diff` is combined to,
    /// and the result is stored to the db, keyed by `last_version`.
    pub fn bump_ledger_counters(
        &self, first_version: Version, last_version: Version,
        cs: &mut ChangeSet,
    ) -> Result<LedgerCounters> {
        assert!(first_version <= last_version);
        let mut counters = if first_version > 0 {
            let base_version = first_version - 1;
            if let Some(counters) =
                self.db.get::<LedgerCountersSchema>(&base_version)?
            {
                counters
            } else {
                diem_warn!(
                    base_version = base_version,
                    "Base version ledger counters not found. Assuming zeros.",
                );
                LedgerCounters::new()
            }
        } else {
            LedgerCounters::new()
        };
        (first_version..=last_version)
            .map(|v| {
                let bumps = cs.counter_bumps(v);
                counters.bump(bumps);
                cs.batch.put::<LedgerCountersSchema>(&v, &counters)
            })
            .collect::<Result<Vec<_>>>()?;
        Ok(counters)
    }
}
#[cfg(test)]
mod test;