Skip to main content

soil_network/sync/
block_relay_protocol.rs

1// This file is part of Soil.
2
3// Copyright (C) Soil contributors.
4// Copyright (C) Parity Technologies (UK) Ltd.
5// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
6
7//! Block relay protocol related definitions.
8
9use futures::channel::oneshot;
10use soil_network::common::sync::message::{BlockData, BlockRequest};
11use soil_network::types::PeerId;
12use soil_network::{request_responses::RequestFailure, NetworkBackend, ProtocolName};
13use std::{fmt, sync::Arc};
14use subsoil::runtime::traits::Block as BlockT;
15
16/// The serving side of the block relay protocol. It runs a single instance
17/// of the server task that processes the incoming protocol messages.
18#[async_trait::async_trait]
19pub trait BlockServer<Block: BlockT>: Send {
20	/// Starts the protocol processing.
21	async fn run(&mut self);
22}
23
24/// The client side stub to download blocks from peers. This is a handle
25/// that can be used to initiate concurrent downloads.
26#[async_trait::async_trait]
27pub trait BlockDownloader<Block: BlockT>: fmt::Debug + Send + Sync {
28	/// Protocol name used by block downloader.
29	fn protocol_name(&self) -> &ProtocolName;
30
31	/// Performs the protocol specific sequence to fetch the blocks from the peer.
32	/// Output: if the download succeeds, the response is a `Vec<u8>` which is
33	/// in a format specific to the protocol implementation. The block data
34	/// can be extracted from this response using [`BlockDownloader::block_response_into_blocks`].
35	async fn download_blocks(
36		&self,
37		who: PeerId,
38		request: BlockRequest<Block>,
39	) -> Result<Result<(Vec<u8>, ProtocolName), RequestFailure>, oneshot::Canceled>;
40
41	/// Parses the protocol specific response to retrieve the block data.
42	fn block_response_into_blocks(
43		&self,
44		request: &BlockRequest<Block>,
45		response: Vec<u8>,
46	) -> Result<Vec<BlockData<Block>>, BlockResponseError>;
47}
48
49/// Errors returned by [`BlockDownloader::block_response_into_blocks`].
50#[derive(Debug)]
51pub enum BlockResponseError {
52	/// Failed to decode the response bytes.
53	DecodeFailed(String),
54
55	/// Failed to extract the blocks from the decoded bytes.
56	ExtractionFailed(String),
57}
58
59/// Block relay specific params for network creation, specified in
60/// ['soil_service::BuildNetworkParams'].
61pub struct BlockRelayParams<Block: BlockT, N: NetworkBackend<Block, <Block as BlockT>::Hash>> {
62	pub server: Box<dyn BlockServer<Block>>,
63	pub downloader: Arc<dyn BlockDownloader<Block>>,
64	pub request_response_config: N::RequestResponseProtocolConfig,
65}