oasis_core_runtime/consensus/state/
mod.rs

1//! Consensus state wrappers.
2use std::sync::Arc;
3
4use anyhow::{Error, Result};
5use thiserror::Error;
6
7use crate::{
8    protocol::Protocol,
9    storage::mkvs::{sync::HostReadSyncer, ImmutableMKVS, Root, Tree},
10    types::{self, HostStorageEndpoint},
11};
12
13pub mod beacon;
14pub mod keymanager;
15pub mod registry;
16pub mod roothash;
17pub mod staking;
18
19#[derive(Error, Debug)]
20pub enum StateError {
21    #[error("consensus state: unavailable/corrupted state: {0}")]
22    Unavailable(#[from] Error),
23}
24
25impl From<StateError> for types::Error {
26    fn from(e: StateError) -> Self {
27        Self {
28            module: "consensus".to_string(),
29            code: 1,
30            message: e.to_string(),
31        }
32    }
33}
34
35/// Provides consensus state tree from the host.
36pub struct ConsensusState {
37    // An explicit height field is needed because the relationship between the underlying consensus
38    // height and the corresponding state root is a consensus backend implementation detail.
39    height: u64,
40    mkvs: Tree,
41}
42
43impl ConsensusState {
44    /// Creates a consensus state wrapping the provided tree.
45    pub fn new(height: u64, tree: Tree) -> Self {
46        Self { height, mkvs: tree }
47    }
48
49    /// Creates consensus state using host protocol.
50    pub fn from_protocol(protocol: Arc<Protocol>, height: u64, root: Root) -> Self {
51        let read_syncer = HostReadSyncer::new(protocol, HostStorageEndpoint::Consensus);
52        Self {
53            height,
54            mkvs: Tree::builder()
55                .with_capacity(100_000, 10_000_000)
56                .with_root(root)
57                .build(Box::new(read_syncer)),
58        }
59    }
60
61    /// Consensus layer height that this data is for.
62    pub fn height(&self) -> u64 {
63        self.height
64    }
65}
66
67impl ImmutableMKVS for ConsensusState {
68    fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>> {
69        self.mkvs.get(key)
70    }
71
72    fn get_proof(&self, key: &[u8]) -> Result<Option<crate::storage::mkvs::sync::Proof>> {
73        self.mkvs.get_proof(key)
74    }
75
76    fn prefetch_prefixes(
77        &self,
78        prefixes: &[crate::storage::mkvs::Prefix],
79        limit: u16,
80    ) -> Result<()> {
81        self.mkvs.prefetch_prefixes(prefixes, limit)
82    }
83
84    fn iter(&self) -> Box<dyn crate::storage::mkvs::Iterator + '_> {
85        Box::new(self.mkvs.iter())
86    }
87}
88
89impl ImmutableMKVS for &ConsensusState {
90    fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>> {
91        self.mkvs.get(key)
92    }
93
94    fn get_proof(&self, key: &[u8]) -> Result<Option<crate::storage::mkvs::sync::Proof>> {
95        self.mkvs.get_proof(key)
96    }
97
98    fn prefetch_prefixes(
99        &self,
100        prefixes: &[crate::storage::mkvs::Prefix],
101        limit: u16,
102    ) -> Result<()> {
103        self.mkvs.prefetch_prefixes(prefixes, limit)
104    }
105
106    fn iter(&self) -> Box<dyn crate::storage::mkvs::Iterator + '_> {
107        Box::new(self.mkvs.iter())
108    }
109}