1// This file is part of Substrate.
23// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
56// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
1011// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
1516// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <https://www.gnu.org/licenses/>.
1819//! Common syncing types.
2021use futures::Stream;
22use sc_network_common::{role::Roles, types::ReputationChange};
2324use crate::strategy::{state_sync::StateSyncProgress, warp::WarpSyncProgress};
2526use sc_network_types::PeerId;
27use sp_runtime::traits::{Block as BlockT, NumberFor};
2829use std::{fmt, pin::Pin, sync::Arc};
3031/// The sync status of a peer we are trying to sync with
32#[derive(Debug)]
33pub struct PeerInfo<Block: BlockT> {
34/// Their best block hash.
35pub best_hash: Block::Hash,
36/// Their best block number.
37pub best_number: NumberFor<Block>,
38}
3940/// Info about a peer's known state (both full and light).
41#[derive(Debug)]
42pub struct ExtendedPeerInfo<B: BlockT> {
43/// Roles
44pub roles: Roles,
45/// Peer best block hash
46pub best_hash: B::Hash,
47/// Peer best block number
48pub best_number: NumberFor<B>,
49}
5051impl<B> Clone for ExtendedPeerInfo<B>
52where
53B: BlockT,
54{
55fn clone(&self) -> Self {
56Self { roles: self.roles, best_hash: self.best_hash, best_number: self.best_number }
57 }
58}
5960impl<B> Copy for ExtendedPeerInfo<B> where B: BlockT {}
6162/// Reported sync state.
63#[derive(Clone, Eq, PartialEq, Debug)]
64pub enum SyncState<BlockNumber> {
65/// Initial sync is complete, keep-up sync is active.
66Idle,
67/// Actively catching up with the chain.
68Downloading { target: BlockNumber },
69/// All blocks are downloaded and are being imported.
70Importing { target: BlockNumber },
71}
7273impl<BlockNumber> SyncState<BlockNumber> {
74/// Are we actively catching up with the chain?
75pub fn is_major_syncing(&self) -> bool {
76 !matches!(self, SyncState::Idle)
77 }
78}
7980/// Syncing status and statistics.
81#[derive(Debug, Clone)]
82pub struct SyncStatus<Block: BlockT> {
83/// Current global sync state.
84pub state: SyncState<NumberFor<Block>>,
85/// Target sync block number.
86pub best_seen_block: Option<NumberFor<Block>>,
87/// Number of peers participating in syncing.
88pub num_peers: u32,
89/// Number of blocks queued for import
90pub queued_blocks: u32,
91/// State sync status in progress, if any.
92pub state_sync: Option<StateSyncProgress>,
93/// Warp sync in progress, if any.
94pub warp_sync: Option<WarpSyncProgress<Block>>,
95}
9697/// A peer did not behave as expected and should be reported.
98#[derive(Debug, Clone, PartialEq, Eq)]
99pub struct BadPeer(pub PeerId, pub ReputationChange);
100101impl fmt::Display for BadPeer {
102fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
103write!(f, "Bad peer {}; Reputation change: {:?}", self.0, self.1)
104 }
105}
106107impl std::error::Error for BadPeer {}
108109/// Provides high-level status of syncing.
110#[async_trait::async_trait]
111pub trait SyncStatusProvider<Block: BlockT>: Send + Sync {
112/// Get high-level view of the syncing status.
113async fn status(&self) -> Result<SyncStatus<Block>, ()>;
114}
115116#[async_trait::async_trait]
117impl<T, Block> SyncStatusProvider<Block> for Arc<T>
118where
119T: ?Sized,
120 T: SyncStatusProvider<Block>,
121 Block: BlockT,
122{
123async fn status(&self) -> Result<SyncStatus<Block>, ()> {
124 T::status(self).await
125}
126}
127128/// Syncing-related events that other protocols can subscribe to.
129pub enum SyncEvent {
130/// Peer that the syncing implementation is tracking connected.
131PeerConnected(PeerId),
132133/// Peer that the syncing implementation was tracking disconnected.
134PeerDisconnected(PeerId),
135}
136137pub trait SyncEventStream: Send + Sync {
138/// Subscribe to syncing-related events.
139fn event_stream(&self, name: &'static str) -> Pin<Box<dyn Stream<Item = SyncEvent> + Send>>;
140}
141142impl<T> SyncEventStream for Arc<T>
143where
144T: ?Sized,
145 T: SyncEventStream,
146{
147fn event_stream(&self, name: &'static str) -> Pin<Box<dyn Stream<Item = SyncEvent> + Send>> {
148 T::event_stream(self, name)
149 }
150}