use std::fs::File;
use crate::core::core::pmmr::RewindablePMMR;
use crate::core::core::{BlockHeader, TxKernel};
use crate::error::{Error, ErrorKind};
use crate::store::Batch;
use grin_store::pmmr::PMMRBackend;
pub struct RewindableKernelView<'a> {
pmmr: RewindablePMMR<'a, TxKernel, PMMRBackend<TxKernel>>,
batch: &'a Batch<'a>,
header: BlockHeader,
}
impl<'a> RewindableKernelView<'a> {
pub fn new(
pmmr: RewindablePMMR<'a, TxKernel, PMMRBackend<TxKernel>>,
batch: &'a Batch<'_>,
header: BlockHeader,
) -> RewindableKernelView<'a> {
RewindableKernelView {
pmmr,
batch,
header,
}
}
pub fn batch(&self) -> &'a Batch<'_> {
self.batch
}
pub fn rewind(&mut self, header: &BlockHeader) -> Result<(), Error> {
self.pmmr
.rewind(header.kernel_mmr_size)
.map_err(&ErrorKind::TxHashSetErr)?;
self.header = header.clone();
Ok(())
}
pub fn validate_root(&self) -> Result<(), Error> {
let root = self.pmmr.root().map_err(|_| ErrorKind::InvalidRoot)?;
if root != self.header.kernel_root {
return Err(ErrorKind::InvalidTxHashSet(format!(
"Kernel root at {} does not match",
self.header.height
))
.into());
}
Ok(())
}
pub fn kernel_data_read(&self) -> Result<File, Error> {
let file = self
.pmmr
.backend()
.data_as_temp_file()
.map_err(|_| ErrorKind::FileReadErr("Data file woes".into()))?;
Ok(file)
}
}