use super::BlockStatus;
use futures::FutureExt as _;
use std::{error::Error, future::Future, pin::Pin, sync::Arc};
use subsoil::runtime::traits::Block;
pub trait Chain<B: Block> {
fn block_status(&self, hash: B::Hash) -> Result<BlockStatus, Box<dyn Error + Send>>;
}
impl<T: Chain<B>, B: Block> Chain<B> for Arc<T> {
fn block_status(&self, hash: B::Hash) -> Result<BlockStatus, Box<dyn Error + Send>> {
(&**self).block_status(hash)
}
}
#[derive(Debug, PartialEq, Eq)]
pub enum Validation {
Success {
is_new_best: bool,
},
Failure {
disconnect: bool,
},
}
pub trait BlockAnnounceValidator<B: Block> {
fn validate(
&mut self,
header: &B::Header,
data: &[u8],
) -> Pin<Box<dyn Future<Output = Result<Validation, Box<dyn Error + Send>>> + Send>>;
}
#[derive(Debug)]
pub struct DefaultBlockAnnounceValidator;
impl<B: Block> BlockAnnounceValidator<B> for DefaultBlockAnnounceValidator {
fn validate(
&mut self,
_: &B::Header,
data: &[u8],
) -> Pin<Box<dyn Future<Output = Result<Validation, Box<dyn Error + Send>>> + Send>> {
let is_empty = data.is_empty();
async move {
if !is_empty {
log::debug!(
target: "sync",
"Received unknown data alongside the block announcement.",
);
Ok(Validation::Failure { disconnect: true })
} else {
Ok(Validation::Success { is_new_best: false })
}
}
.boxed()
}
}