consensus_core/storage/
mod.rs

1// Copyright (c) Mysten Labs, Inc.
2// Modifications Copyright (c) 2024 IOTA Stiftung
3// SPDX-License-Identifier: Apache-2.0
4
5#[cfg(test)]
6pub(crate) mod mem_store;
7pub(crate) mod rocksdb_store;
8
9#[cfg(test)]
10mod store_tests;
11
12use consensus_config::AuthorityIndex;
13
14use crate::{
15    CommitIndex,
16    block::{BlockRef, Round, VerifiedBlock},
17    commit::{CommitInfo, CommitRange, CommitRef, TrustedCommit},
18    error::ConsensusResult,
19};
20
21/// A common interface for consensus storage.
22pub(crate) trait Store: Send + Sync {
23    /// Writes blocks, consensus commits and other data to store atomically.
24    fn write(&self, write_batch: WriteBatch) -> ConsensusResult<()>;
25
26    /// Reads blocks for the given refs.
27    fn read_blocks(&self, refs: &[BlockRef]) -> ConsensusResult<Vec<Option<VerifiedBlock>>>;
28
29    /// Checks if blocks exist in the store.
30    fn contains_blocks(&self, refs: &[BlockRef]) -> ConsensusResult<Vec<bool>>;
31
32    /// Checks whether there is any block at the given slot
33    #[allow(dead_code)]
34    fn contains_block_at_slot(&self, slot: crate::block::Slot) -> ConsensusResult<bool>;
35
36    /// Reads blocks for an authority, from start_round.
37    fn scan_blocks_by_author(
38        &self,
39        authority: AuthorityIndex,
40        start_round: Round,
41    ) -> ConsensusResult<Vec<VerifiedBlock>>;
42
43    // The method reads and returns all metrics stored. Used for restoring the
44    // scoring metrics in case of DagState initialization from storage
45    fn scan_scoring_metrics(&self)
46    -> ConsensusResult<Vec<(AuthorityIndex, StorageScoringMetrics)>>;
47
48    // The method returns the last `num_of_rounds` rounds blocks by author in round
49    // ascending order. When a `before_round` is defined then the blocks of
50    // round `<=before_round` are returned. If not then the max value for round
51    // will be used as cut off.
52    #[allow(dead_code)]
53    fn scan_last_blocks_by_author(
54        &self,
55        author: AuthorityIndex,
56        num_of_rounds: u64,
57        before_round: Option<Round>,
58    ) -> ConsensusResult<Vec<VerifiedBlock>>;
59
60    /// Reads the last commit.
61    fn read_last_commit(&self) -> ConsensusResult<Option<TrustedCommit>>;
62
63    /// Reads all commits from start (inclusive) until end (inclusive).
64    fn scan_commits(&self, range: CommitRange) -> ConsensusResult<Vec<TrustedCommit>>;
65
66    /// Reads all blocks voting on a particular commit.
67    fn read_commit_votes(&self, commit_index: CommitIndex) -> ConsensusResult<Vec<BlockRef>>;
68
69    /// Reads the last commit info, written atomically with the last commit.
70    fn read_last_commit_info(&self) -> ConsensusResult<Option<(CommitRef, CommitInfo)>>;
71}
72
73/// Represents data to be written to the store together atomically.
74#[derive(Debug, Default)]
75pub(crate) struct WriteBatch {
76    pub(crate) blocks: Vec<VerifiedBlock>,
77    pub(crate) commits: Vec<TrustedCommit>,
78    pub(crate) commit_info: Vec<(CommitRef, CommitInfo)>,
79    pub(crate) scoring_metrics: Vec<(AuthorityIndex, StorageScoringMetrics)>,
80}
81
82impl WriteBatch {
83    pub(crate) fn new(
84        blocks: Vec<VerifiedBlock>,
85        commits: Vec<TrustedCommit>,
86        commit_info: Vec<(CommitRef, CommitInfo)>,
87        scoring_metrics: Vec<(AuthorityIndex, StorageScoringMetrics)>,
88    ) -> Self {
89        WriteBatch {
90            blocks,
91            commits,
92            commit_info,
93            scoring_metrics,
94        }
95    }
96
97    // Test setters.
98
99    #[cfg(test)]
100    pub(crate) fn blocks(mut self, blocks: Vec<VerifiedBlock>) -> Self {
101        self.blocks = blocks;
102        self
103    }
104
105    #[cfg(test)]
106    pub(crate) fn commits(mut self, commits: Vec<TrustedCommit>) -> Self {
107        self.commits = commits;
108        self
109    }
110
111    #[cfg(test)]
112    pub(crate) fn commit_info(mut self, commit_info: Vec<(CommitRef, CommitInfo)>) -> Self {
113        self.commit_info = commit_info;
114        self
115    }
116
117    #[cfg(test)]
118    pub(crate) fn scoring_metrics(
119        mut self,
120        scoring_metrics: Vec<(AuthorityIndex, StorageScoringMetrics)>,
121    ) -> Self {
122        self.scoring_metrics = scoring_metrics;
123        self
124    }
125}
126
127// This struct is used in storage. It holds the same data as
128// `UncachedScoringMetrics`, but uses `u64` instead of `AtomicU64`.
129#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq)]
130pub(crate) struct StorageScoringMetrics {
131    pub(crate) faulty_blocks_provable: u64,
132    pub(crate) faulty_blocks_unprovable: u64,
133    pub(crate) equivocations: u64,
134    pub(crate) missing_proposals: u64,
135}