use std::collections::{HashMap, HashSet};
use sp_runtime::traits::{Block as BlockT, NumberFor};
use sc_client_api::{BadBlocks, ForkBlocks};
pub enum LookupResult<B: BlockT> {
NotSpecial,
KnownBad,
Expected(B::Hash),
}
pub struct BlockRules<B: BlockT> {
bad: HashSet<B::Hash>,
forks: HashMap<NumberFor<B>, B::Hash>,
}
impl<B: BlockT> BlockRules<B> {
pub fn new(fork_blocks: ForkBlocks<B>, bad_blocks: BadBlocks<B>) -> Self {
Self {
bad: bad_blocks.unwrap_or_default(),
forks: fork_blocks.unwrap_or_default().into_iter().collect(),
}
}
pub fn mark_bad(&mut self, hash: B::Hash) {
self.bad.insert(hash);
}
pub fn lookup(&self, number: NumberFor<B>, hash: &B::Hash) -> LookupResult<B> {
if let Some(hash_for_height) = self.forks.get(&number) {
if hash_for_height != hash {
return LookupResult::Expected(*hash_for_height);
}
}
if self.bad.contains(hash) {
return LookupResult::KnownBad;
}
LookupResult::NotSpecial
}
}