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    metrics::StoredScoringMetricsU64,
20};
21
22/// A common interface for consensus storage.
23pub(crate) trait Store: Send + Sync {
24    /// Writes blocks, consensus commits and other data to store atomically.
25    fn write(&self, write_batch: WriteBatch) -> ConsensusResult<()>;
26
27    /// Reads blocks for the given refs.
28    fn read_blocks(&self, refs: &[BlockRef]) -> ConsensusResult<Vec<Option<VerifiedBlock>>>;
29
30    /// Checks if blocks exist in the store.
31    fn contains_blocks(&self, refs: &[BlockRef]) -> ConsensusResult<Vec<bool>>;
32
33    /// Checks whether there is any block at the given slot
34    #[allow(dead_code)]
35    fn contains_block_at_slot(&self, slot: crate::block::Slot) -> ConsensusResult<bool>;
36
37    /// Reads blocks for an authority, from start_round.
38    fn scan_blocks_by_author(
39        &self,
40        authority: AuthorityIndex,
41        start_round: Round,
42    ) -> ConsensusResult<Vec<VerifiedBlock>>;
43
44    // The method reads and returns all metrics stored. Used for restoring the
45    // scoring metrics in case of DagState initialization from storage
46    fn scan_metrics(&self) -> ConsensusResult<Vec<(AuthorityIndex, StoredScoringMetricsU64)>>;
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, StoredScoringMetricsU64)>,
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, StoredScoringMetricsU64)>,
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}