use std::{fmt, collections::HashSet};
use futures::channel::mpsc;
use sp_core::storage::StorageKey;
use sp_runtime::{
traits::{Block as BlockT, NumberFor},
generic::BlockId
};
use sp_consensus::BlockOrigin;
use crate::blockchain::Info;
use crate::notifications::StorageEventStream;
use sp_blockchain;
pub type ImportNotifications<Block> = mpsc::UnboundedReceiver<BlockImportNotification<Block>>;
pub type FinalityNotifications<Block> = mpsc::UnboundedReceiver<FinalityNotification<Block>>;
pub type ForkBlocks<Block> = Option<Vec<(NumberFor<Block>, <Block as BlockT>::Hash)>>;
pub type BadBlocks<Block> = Option<HashSet<<Block as BlockT>::Hash>>;
pub trait BlockOf {
type Type: BlockT;
}
pub trait BlockchainEvents<Block: BlockT> {
fn import_notification_stream(&self) -> ImportNotifications<Block>;
fn finality_notification_stream(&self) -> FinalityNotifications<Block>;
fn storage_changes_notification_stream(
&self,
filter_keys: Option<&[StorageKey]>,
child_filter_keys: Option<&[(StorageKey, Option<Vec<StorageKey>>)]>,
) -> sp_blockchain::Result<StorageEventStream<Block::Hash>>;
}
pub trait BlockBody<Block: BlockT> {
fn block_body(&self,
id: &BlockId<Block>
) -> sp_blockchain::Result<Option<Vec<<Block as BlockT>::Extrinsic>>>;
}
pub trait ProvideUncles<Block: BlockT> {
fn uncles(&self, target_hash: Block::Hash, max_generation: NumberFor<Block>)
-> sp_blockchain::Result<Vec<Block::Header>>;
}
#[derive(Debug)]
pub struct ClientInfo<Block: BlockT> {
pub chain: Info<Block>,
pub usage: Option<UsageInfo>,
}
#[derive(Default, Clone, Debug)]
pub struct MemoryInfo {
pub state_cache: usize,
pub database_cache: usize,
}
#[derive(Default, Clone, Debug)]
pub struct IoInfo {
pub transactions: u64,
pub bytes_read: u64,
pub bytes_written: u64,
pub writes: u64,
pub reads: u64,
pub average_transaction_size: u64,
pub state_reads: u64,
pub state_reads_cache: u64,
pub state_writes: u64,
}
#[derive(Default, Clone, Debug)]
pub struct UsageInfo {
pub memory: MemoryInfo,
pub io: IoInfo,
}
impl fmt::Display for UsageInfo {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f,
"caches: ({} state, {} db overlay), i/o: ({} tx, {} write, {} read, {} avg tx, {}/{} key cache reads/total, {} key writes)",
self.memory.state_cache,
self.memory.database_cache,
self.io.transactions,
self.io.bytes_written,
self.io.bytes_read,
self.io.average_transaction_size,
self.io.state_reads_cache,
self.io.state_reads,
self.io.state_writes,
)
}
}
#[derive(Clone, Debug)]
pub struct BlockImportNotification<Block: BlockT> {
pub hash: Block::Hash,
pub origin: BlockOrigin,
pub header: Block::Header,
pub is_new_best: bool,
pub retracted: Vec<Block::Hash>,
}
#[derive(Clone, Debug)]
pub struct FinalityNotification<Block: BlockT> {
pub hash: Block::Hash,
pub header: Block::Header,
}