sc_network_sync/block_relay_protocol.rs
1// Copyright (C) Parity Technologies (UK) Ltd.
2// This file is part of Substrate.
3// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
4
5// Substrate is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9
10// Substrate is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14
15// You should have received a copy of the GNU General Public License
16// along with Substrate. If not, see <https://www.gnu.org/licenses/>.
17
18//! Block relay protocol related definitions.
19
20use futures::channel::oneshot;
21use sc_network::{request_responses::RequestFailure, NetworkBackend, ProtocolName};
22use sc_network_common::sync::message::{BlockData, BlockRequest};
23use sc_network_types::PeerId;
24use sp_runtime::traits::Block as BlockT;
25use std::{fmt, sync::Arc};
26
27/// The serving side of the block relay protocol. It runs a single instance
28/// of the server task that processes the incoming protocol messages.
29#[async_trait::async_trait]
30pub trait BlockServer<Block: BlockT>: Send {
31 /// Starts the protocol processing.
32 async fn run(&mut self);
33}
34
35/// The client side stub to download blocks from peers. This is a handle
36/// that can be used to initiate concurrent downloads.
37#[async_trait::async_trait]
38pub trait BlockDownloader<Block: BlockT>: fmt::Debug + Send + Sync {
39 /// Protocol name used by block downloader.
40 fn protocol_name(&self) -> &ProtocolName;
41
42 /// Performs the protocol specific sequence to fetch the blocks from the peer.
43 /// Output: if the download succeeds, the response is a `Vec<u8>` which is
44 /// in a format specific to the protocol implementation. The block data
45 /// can be extracted from this response using [`BlockDownloader::block_response_into_blocks`].
46 async fn download_blocks(
47 &self,
48 who: PeerId,
49 request: BlockRequest<Block>,
50 ) -> Result<Result<(Vec<u8>, ProtocolName), RequestFailure>, oneshot::Canceled>;
51
52 /// Parses the protocol specific response to retrieve the block data.
53 fn block_response_into_blocks(
54 &self,
55 request: &BlockRequest<Block>,
56 response: Vec<u8>,
57 ) -> Result<Vec<BlockData<Block>>, BlockResponseError>;
58}
59
60/// Errors returned by [`BlockDownloader::block_response_into_blocks`].
61#[derive(Debug)]
62pub enum BlockResponseError {
63 /// Failed to decode the response bytes.
64 DecodeFailed(String),
65
66 /// Failed to extract the blocks from the decoded bytes.
67 ExtractionFailed(String),
68}
69
70/// Block relay specific params for network creation, specified in
71/// ['sc_service::BuildNetworkParams'].
72pub struct BlockRelayParams<Block: BlockT, N: NetworkBackend<Block, <Block as BlockT>::Hash>> {
73 pub server: Box<dyn BlockServer<Block>>,
74 pub downloader: Arc<dyn BlockDownloader<Block>>,
75 pub request_response_config: N::RequestResponseProtocolConfig,
76}