use std::cmp::Ordering;
use anyhow::{anyhow, Result};
use node_data::ledger::Header;
use tracing::info;
use super::acceptor::{Acceptor, RevertTarget};
use crate::database::{self};
use crate::{vm, Network};
pub(crate) struct WithContext<
'a,
N: Network,
DB: database::DB,
VM: vm::VMExecution,
> {
acc: &'a Acceptor<N, DB, VM>,
}
impl<'a, N: Network, DB: database::DB, VM: vm::VMExecution>
WithContext<'a, N, DB, VM>
{
pub(crate) fn new(acc: &'a Acceptor<N, DB, VM>) -> Self {
Self { acc }
}
pub(crate) async fn try_revert(
&self,
local: &Header,
remote: &Header,
revert_target: RevertTarget,
) -> Result<()> {
match (local.height, remote.iteration.cmp(&local.iteration)) {
(0, _) => Err(anyhow!("cannot fallback over genesis block")),
(_, Ordering::Greater) => Err(anyhow!(
"iteration {:?} is higher than the current {:?}",
remote.iteration,
local.iteration
)),
(_, Ordering::Equal) => Err(anyhow!(
"iteration is equal to the current {:?}",
local.iteration
)), _ => Ok(()),
}?;
info!(
event = "execute fallback checks",
height = local.height,
iter = local.iteration,
target_iter = remote.iteration,
);
self.acc.verify_header_against_local(local, remote).await?;
self.acc.try_revert(revert_target).await
}
}