use std::sync::Arc;
use miden_node_utils::block_cache::BlockOrderedCache;
use miden_protocol::block::BlockNumber;
use crate::errors::DatabaseError;
use crate::state::State;
#[derive(Clone, Debug)]
pub struct BlockNotification(Arc<Block>);
impl BlockNotification {
pub fn new(block_num: BlockNumber, block_bytes: Vec<u8>) -> Self {
Self(Arc::new(Block { block_num, block_bytes }))
}
pub fn block_num(&self) -> BlockNumber {
self.0.block_num
}
pub fn block_bytes(&self) -> &[u8] {
&self.0.block_bytes
}
}
#[derive(Clone, Debug)]
struct Block {
pub block_num: BlockNumber,
pub block_bytes: Vec<u8>,
}
#[derive(Clone, Debug)]
pub struct ProofNotification(Arc<Proof>);
impl ProofNotification {
pub fn new(block_num: BlockNumber, proof_bytes: Vec<u8>) -> Self {
Self(Arc::new(Proof { block_num, proof_bytes }))
}
pub fn block_num(&self) -> BlockNumber {
self.0.block_num
}
pub fn proof_bytes(&self) -> &[u8] {
&self.0.proof_bytes
}
}
#[derive(Clone, Debug)]
struct Proof {
block_num: BlockNumber,
proof_bytes: Vec<u8>,
}
pub type BlockCache = BlockOrderedCache<BlockNotification>;
pub type ProofCache = BlockOrderedCache<ProofNotification>;
impl State {
pub async fn load_block(
&self,
block_num: BlockNumber,
) -> Result<Option<Vec<u8>>, DatabaseError> {
if block_num > self.committed_tip() {
return Ok(None);
}
if let Some(block) = self.block_cache.get(block_num) {
return Ok(Some(block.block_bytes().to_vec()));
}
self.block_store.load_block(block_num).await.map_err(Into::into)
}
pub async fn load_proof(
&self,
block_num: BlockNumber,
) -> Result<Option<Vec<u8>>, DatabaseError> {
if block_num > self.proven_tip() {
return Ok(None);
}
if let Some(proof) = self.proof_cache.get(block_num) {
return Ok(Some(proof.proof_bytes().to_vec()));
}
self.block_store.load_proof(block_num).await.map_err(Into::into)
}
pub async fn load_proving_inputs(
&self,
block_num: BlockNumber,
) -> std::io::Result<Option<Vec<u8>>> {
self.block_store.load_proving_inputs(block_num).await
}
}