1pub mod chain_sync;
26mod disconnected_peers;
27pub mod polkadot;
28pub mod state;
29pub mod state_sync;
30pub mod warp;
31
32use crate::{
33	pending_responses::ResponseFuture,
34	service::network::NetworkServiceHandle,
35	types::{BadPeer, SyncStatus},
36};
37use sc_consensus::{BlockImportError, BlockImportStatus, IncomingBlock};
38use sc_network::ProtocolName;
39use sc_network_common::sync::message::BlockAnnounce;
40use sc_network_types::PeerId;
41use sp_blockchain::Error as ClientError;
42use sp_consensus::BlockOrigin;
43use sp_runtime::{
44	traits::{Block as BlockT, NumberFor},
45	Justifications,
46};
47use std::any::Any;
48
49pub trait SyncingStrategy<B: BlockT>: Send
51where
52	B: BlockT,
53{
54	fn add_peer(&mut self, peer_id: PeerId, best_hash: B::Hash, best_number: NumberFor<B>);
56
57	fn remove_peer(&mut self, peer_id: &PeerId);
59
60	#[must_use]
64	fn on_validated_block_announce(
65		&mut self,
66		is_best: bool,
67		peer_id: PeerId,
68		announce: &BlockAnnounce<B::Header>,
69	) -> Option<(B::Hash, NumberFor<B>)>;
70
71	fn set_sync_fork_request(&mut self, peers: Vec<PeerId>, hash: &B::Hash, number: NumberFor<B>);
79
80	fn request_justification(&mut self, hash: &B::Hash, number: NumberFor<B>);
82
83	fn clear_justification_requests(&mut self);
85
86	fn on_justification_import(&mut self, hash: B::Hash, number: NumberFor<B>, success: bool);
88
89	fn on_generic_response(
94		&mut self,
95		peer_id: &PeerId,
96		key: StrategyKey,
97		protocol_name: ProtocolName,
98		response: Box<dyn Any + Send>,
99	);
100
101	fn on_blocks_processed(
106		&mut self,
107		imported: usize,
108		count: usize,
109		results: Vec<(Result<BlockImportStatus<NumberFor<B>>, BlockImportError>, B::Hash)>,
110	);
111
112	fn on_block_finalized(&mut self, hash: &B::Hash, number: NumberFor<B>);
114
115	fn update_chain_info(&mut self, best_hash: &B::Hash, best_number: NumberFor<B>);
117
118	fn is_major_syncing(&self) -> bool;
120
121	fn num_peers(&self) -> usize;
123
124	fn status(&self) -> SyncStatus<B>;
126
127	fn num_downloaded_blocks(&self) -> usize;
129
130	fn num_sync_requests(&self) -> usize;
132
133	#[must_use]
135	fn actions(
136		&mut self,
137		network_service: &NetworkServiceHandle,
139	) -> Result<Vec<SyncingAction<B>>, ClientError>;
140}
141
142#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
144pub struct StrategyKey(&'static str);
145
146impl StrategyKey {
147	pub const fn new(key: &'static str) -> Self {
149		Self(key)
150	}
151}
152
153pub enum SyncingAction<B: BlockT> {
154	StartRequest {
156		peer_id: PeerId,
157		key: StrategyKey,
158		request: ResponseFuture,
159		remove_obsolete: bool,
161	},
162	CancelRequest { peer_id: PeerId, key: StrategyKey },
164	DropPeer(BadPeer),
166	ImportBlocks { origin: BlockOrigin, blocks: Vec<IncomingBlock<B>> },
168	ImportJustifications {
170		peer_id: PeerId,
171		hash: B::Hash,
172		number: NumberFor<B>,
173		justifications: Justifications,
174	},
175	Finished,
177}
178
179impl<B> std::fmt::Debug for SyncingAction<B>
182where
183	B: BlockT,
184{
185	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
186		match &self {
187			Self::StartRequest { peer_id, key, remove_obsolete, .. } => {
188				write!(
189					f,
190					"StartRequest {{ peer_id: {:?}, key: {:?}, remove_obsolete: {:?} }}",
191					peer_id, key, remove_obsolete
192				)
193			},
194			Self::CancelRequest { peer_id, key } => {
195				write!(f, "CancelRequest {{ peer_id: {:?}, key: {:?} }}", peer_id, key)
196			},
197			Self::DropPeer(peer) => write!(f, "DropPeer({:?})", peer),
198			Self::ImportBlocks { blocks, .. } => write!(f, "ImportBlocks({:?})", blocks),
199			Self::ImportJustifications { hash, number, .. } => {
200				write!(f, "ImportJustifications({:?}, {:?})", hash, number)
201			},
202			Self::Finished => write!(f, "Finished"),
203		}
204	}
205}
206
207impl<B: BlockT> SyncingAction<B> {
208	pub fn is_finished(&self) -> bool {
210		matches!(self, SyncingAction::Finished)
211	}
212
213	#[cfg(test)]
214	pub(crate) fn name(&self) -> &'static str {
215		match self {
216			Self::StartRequest { .. } => "StartRequest",
217			Self::CancelRequest { .. } => "CancelRequest",
218			Self::DropPeer(_) => "DropPeer",
219			Self::ImportBlocks { .. } => "ImportBlocks",
220			Self::ImportJustifications { .. } => "ImportJustifications",
221			Self::Finished => "Finished",
222		}
223	}
224}