use std::sync::Arc;
use anyhow::{anyhow, Result};
use crate::{
core::{
common::namespace::Namespace,
consensus::{state::roothash::ImmutableState as RoothashState, verifier::Verifier},
protocol::Protocol,
storage::mkvs,
types::HostStorageEndpoint,
},
storage,
};
pub struct HostStore {
tree: mkvs::Tree,
}
impl HostStore {
pub fn new(host: Arc<Protocol>, root: mkvs::Root) -> Self {
let read_syncer = mkvs::sync::HostReadSyncer::new(host, HostStorageEndpoint::Runtime);
let tree = mkvs::Tree::builder()
.with_capacity(10_000, 1024 * 1024)
.with_root(root)
.build(Box::new(read_syncer));
Self { tree }
}
pub async fn new_for_round(
host: Arc<Protocol>,
consensus_verifier: &Arc<dyn Verifier>,
id: Namespace,
round: u64,
) -> Result<Self> {
let state = consensus_verifier.latest_state().await?;
let roots = tokio::task::spawn_blocking(move || {
let roothash = RoothashState::new(&state);
roothash.round_roots(id, round)
})
.await??
.ok_or(anyhow!("root not found"))?;
Ok(Self::new(
host,
mkvs::Root {
namespace: id,
version: round,
root_type: mkvs::RootType::State,
hash: roots.state_root,
},
))
}
}
impl storage::Store for HostStore {
fn get(&self, key: &[u8]) -> Option<Vec<u8>> {
self.tree.get(key).unwrap()
}
fn insert(&mut self, key: &[u8], value: &[u8]) {
self.tree.insert(key, value).unwrap();
}
fn remove(&mut self, key: &[u8]) {
self.tree.remove(key).unwrap();
}
fn iter(&self) -> Box<dyn mkvs::Iterator + '_> {
Box::new(self.tree.iter())
}
fn prefetch_prefixes(&mut self, prefixes: Vec<mkvs::Prefix>, limit: u16) {
self.tree.prefetch_prefixes(&prefixes, limit).unwrap();
}
}