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}