oasis_runtime_sdk/storage/
host.rs1use std::sync::Arc;
2
3use anyhow::{anyhow, Result};
4
5use crate::{
6 core::{
7 common::namespace::Namespace,
8 consensus::{state::roothash::ImmutableState as RoothashState, verifier::Verifier},
9 protocol::Protocol,
10 storage::mkvs,
11 types::HostStorageEndpoint,
12 },
13 storage,
14};
15
16pub struct HostStore {
18 tree: mkvs::Tree,
19}
20
21impl HostStore {
22 pub fn new(host: Arc<Protocol>, root: mkvs::Root) -> Self {
24 Self {
25 tree: new_mkvs_tree_for_root(host, root),
26 }
27 }
28
29 pub async fn new_for_round(
34 host: Arc<Protocol>,
35 consensus_verifier: &Arc<dyn Verifier>,
36 runtime_id: Namespace,
37 round: u64,
38 ) -> Result<Self> {
39 Ok(Self {
40 tree: new_mkvs_tree_for_round(
41 host,
42 consensus_verifier,
43 runtime_id,
44 round,
45 mkvs::RootType::State,
46 )
47 .await?,
48 })
49 }
50}
51
52impl storage::Store for HostStore {
53 fn get(&self, key: &[u8]) -> Option<Vec<u8>> {
54 self.tree.get(key).unwrap()
55 }
56
57 fn insert(&mut self, key: &[u8], value: &[u8]) {
58 self.tree.insert(key, value).unwrap();
59 }
60
61 fn remove(&mut self, key: &[u8]) {
62 self.tree.remove(key).unwrap();
63 }
64
65 fn iter(&self) -> Box<dyn mkvs::Iterator + '_> {
66 Box::new(self.tree.iter())
67 }
68
69 fn prefetch_prefixes(&mut self, prefixes: Vec<mkvs::Prefix>, limit: u16) {
70 self.tree.prefetch_prefixes(&prefixes, limit).unwrap();
71 }
72}
73
74pub fn new_mkvs_tree_for_root(host: Arc<Protocol>, root: mkvs::Root) -> mkvs::Tree {
76 let read_syncer = mkvs::sync::HostReadSyncer::new(host, HostStorageEndpoint::Runtime);
77 mkvs::Tree::builder()
78 .with_capacity(10_000, 1024 * 1024)
79 .with_root(root)
80 .build(Box::new(read_syncer))
81}
82
83pub async fn new_mkvs_tree_for_round(
88 host: Arc<Protocol>,
89 consensus_verifier: &Arc<dyn Verifier>,
90 runtime_id: Namespace,
91 round: u64,
92 root_type: mkvs::RootType,
93) -> Result<mkvs::Tree> {
94 let state = consensus_verifier.latest_state().await?;
96 let roots = tokio::task::spawn_blocking(move || {
98 let roothash = RoothashState::new(&state);
99 roothash.round_roots(runtime_id, round)
100 })
101 .await??
102 .ok_or(anyhow!("root not found"))?;
103
104 let root = mkvs::Root {
105 namespace: runtime_id,
106 version: round,
107 root_type,
108 hash: match root_type {
109 mkvs::RootType::State => roots.state_root,
110 mkvs::RootType::IO => roots.io_root,
111 _ => return Err(anyhow!("unsupported root type")),
112 },
113 };
114
115 Ok(new_mkvs_tree_for_root(host, root))
116}