// Copyright 2021 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see .
use futures::channel::oneshot;
use futures::prelude::Future;
use parity_scale_codec::{Decode, Encode, Error as DecodingError};
use sc_network as network;
use sc_network::config as netconfig;
use sc_network::PeerId;
use super::{v1, Protocol};
/// Common properties of any `Request`.
pub trait IsRequest {
/// Each request has a corresponding `Response`.
type Response;
/// What protocol this `Request` implements.
const PROTOCOL: Protocol;
}
/// All requests that can be sent to the network bridge via `NetworkBridgeMessage::SendRequest`.
#[derive(Debug)]
pub enum Requests {
/// Request an availability chunk from a node.
AvailabilityFetching(OutgoingRequest),
}
impl Requests {
/// Get the protocol this request conforms to.
pub fn get_protocol(&self) -> Protocol {
match self {
Self::AvailabilityFetching(_) => Protocol::AvailabilityFetching,
}
}
/// Encode the request.
///
/// The corresponding protocol is returned as well, as we are now leaving typed territory.
///
/// Note: `Requests` is just an enum collecting all supported requests supported by network
/// bridge, it is never sent over the wire. This function just encodes the individual requests
/// contained in the enum.
pub fn encode_request(self) -> (Protocol, OutgoingRequest>) {
match self {
Self::AvailabilityFetching(r) => r.encode_request(),
}
}
}
/// A request to be sent to the network bridge, including a sender for sending responses/failures.
///
/// The network implementation will make use of that sender for informing the requesting subsystem
/// about responses/errors.
#[derive(Debug)]
pub struct OutgoingRequest {
/// Intendent recipient of this request.
pub peer: PeerId,
/// The actual request to send over the wire.
pub payload: Req,
/// Sender which is used by networking to get us back a response.
pub pending_response: oneshot::Sender, network::RequestFailure>>,
}
/// Any error that can occur when sending a request.
pub enum RequestError {
/// Response could not be decoded.
InvalidResponse(DecodingError),
/// Some error in substrate/libp2p happened.
NetworkError(network::RequestFailure),
/// Response got canceled by networking.
Canceled(oneshot::Canceled),
}
impl OutgoingRequest
where
Req: IsRequest + Encode,
Req::Response: Decode,
{
/// Create a new `OutgoingRequest`.
///
/// It will contain a sender that is used by the networking for sending back responses. The
/// connected receiver is returned as the second element in the returned tuple.
pub fn new(
peer: PeerId,
payload: Req,
) -> (
Self,
impl Future