1use futures::Stream;
22use sc_network_common::{role::Roles, types::ReputationChange};
23
24use crate::strategy::{state_sync::StateSyncProgress, warp::WarpSyncProgress};
25
26use sc_network_types::PeerId;
27use sp_runtime::traits::{Block as BlockT, NumberFor};
28
29use std::{fmt, pin::Pin, sync::Arc};
30
31#[derive(Debug)]
33pub struct PeerInfo<Block: BlockT> {
34	pub best_hash: Block::Hash,
36	pub best_number: NumberFor<Block>,
38}
39
40#[derive(Debug)]
42pub struct ExtendedPeerInfo<B: BlockT> {
43	pub roles: Roles,
45	pub best_hash: B::Hash,
47	pub best_number: NumberFor<B>,
49}
50
51impl<B> Clone for ExtendedPeerInfo<B>
52where
53	B: BlockT,
54{
55	fn clone(&self) -> Self {
56		Self { roles: self.roles, best_hash: self.best_hash, best_number: self.best_number }
57	}
58}
59
60impl<B> Copy for ExtendedPeerInfo<B> where B: BlockT {}
61
62#[derive(Clone, Eq, PartialEq, Debug)]
64pub enum SyncState<BlockNumber> {
65	Idle,
67	Downloading { target: BlockNumber },
69	Importing { target: BlockNumber },
71}
72
73impl<BlockNumber> SyncState<BlockNumber> {
74	pub fn is_major_syncing(&self) -> bool {
76		!matches!(self, SyncState::Idle)
77	}
78}
79
80#[derive(Debug, Clone)]
82pub struct SyncStatus<Block: BlockT> {
83	pub state: SyncState<NumberFor<Block>>,
85	pub best_seen_block: Option<NumberFor<Block>>,
87	pub num_peers: u32,
89	pub queued_blocks: u32,
91	pub state_sync: Option<StateSyncProgress>,
93	pub warp_sync: Option<WarpSyncProgress<Block>>,
95}
96
97#[derive(Debug, Clone, PartialEq, Eq)]
99pub struct BadPeer(pub PeerId, pub ReputationChange);
100
101impl fmt::Display for BadPeer {
102	fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
103		write!(f, "Bad peer {}; Reputation change: {:?}", self.0, self.1)
104	}
105}
106
107impl std::error::Error for BadPeer {}
108
109#[async_trait::async_trait]
111pub trait SyncStatusProvider<Block: BlockT>: Send + Sync {
112	async fn status(&self) -> Result<SyncStatus<Block>, ()>;
114}
115
116#[async_trait::async_trait]
117impl<T, Block> SyncStatusProvider<Block> for Arc<T>
118where
119	T: ?Sized,
120	T: SyncStatusProvider<Block>,
121	Block: BlockT,
122{
123	async fn status(&self) -> Result<SyncStatus<Block>, ()> {
124		T::status(self).await
125	}
126}
127
128pub enum SyncEvent {
130	PeerConnected(PeerId),
132
133	PeerDisconnected(PeerId),
135}
136
137pub trait SyncEventStream: Send + Sync {
138	fn event_stream(&self, name: &'static str) -> Pin<Box<dyn Stream<Item = SyncEvent> + Send>>;
140}
141
142impl<T> SyncEventStream for Arc<T>
143where
144	T: ?Sized,
145	T: SyncEventStream,
146{
147	fn event_stream(&self, name: &'static str) -> Pin<Box<dyn Stream<Item = SyncEvent> + Send>> {
148		T::event_stream(self, name)
149	}
150}