use std::{sync::Arc, collections::HashMap}; use async_trait::async_trait; use sp_inherents::CreateInherentDataProviders; use sp_runtime::traits::Block; use sp_api::TransactionFor; use sp_consensus::{Error, CacheKeyId, Environment}; use sc_consensus::{BlockCheckParams, BlockImportParams, ImportResult, BlockImport}; use sc_client_api::Backend; use crate::{ tendermint::{TendermintClient, TendermintImport}, Announce, }; #[async_trait] impl< B: Block, Be: Backend + 'static, C: TendermintClient, CIDP: CreateInherentDataProviders + 'static, E: Send + Sync + Environment + 'static, A: Announce, > BlockImport for TendermintImport where TransactionFor: Send + Sync + 'static, Arc: BlockImport>, as BlockImport>::Error: Into, { type Error = Error; type Transaction = TransactionFor; // TODO: Is there a DoS where you send a block without justifications, causing it to error, // yet adding it to the blacklist in the process preventing further syncing? async fn check_block( &mut self, mut block: BlockCheckParams, ) -> Result { self.verify_order(block.parent_hash, block.number)?; // Does not verify origin here as origin only applies to unfinalized blocks // We don't have context on if this block has justifications or not block.allow_missing_state = false; block.allow_missing_parent = false; self.client.check_block(block).await.map_err(Into::into) } async fn import_block( &mut self, mut block: BlockImportParams>, new_cache: HashMap>, ) -> Result { self.check(&mut block).await?; self.client.import_block(block, new_cache).await.map_err(Into::into) // TODO: If we're a validator who just successfully synced a block, recreate the tendermint // machine with the new height } }