1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
pub mod postcard;

use crate::{
    gossipsub::messages::{
        GossipTopicTag,
        GossipsubBroadcastRequest,
        GossipsubMessage,
    },
    request_response::messages::{
        NetworkResponse,
        OutboundResponse,
        RequestMessage,
        ResponseMessage,
    },
};
use libp2p::request_response::RequestResponseCodec;
use std::io;

/// Implement this in order to handle serialization & deserialization of Gossipsub messages
pub trait GossipsubCodec {
    type RequestMessage;
    type ResponseMessage;

    fn encode(&self, data: Self::RequestMessage) -> Result<Vec<u8>, io::Error>;

    fn decode(
        &self,
        encoded_data: &[u8],
        gossipsub_topic: GossipTopicTag,
    ) -> Result<Self::ResponseMessage, io::Error>;
}

pub trait RequestResponseConverter {
    /// Response that is ready to be converted into NetworkResponse
    type OutboundResponse;
    /// Response that is sent over the network
    type NetworkResponse;
    /// Final Response Message deserialized from IntermediateResponse
    type ResponseMessage;

    fn convert_to_network_response(
        &self,
        res_msg: &Self::OutboundResponse,
    ) -> Result<Self::NetworkResponse, io::Error>;

    fn convert_to_response(
        &self,
        inter_msg: &Self::NetworkResponse,
    ) -> Result<Self::ResponseMessage, io::Error>;
}

/// Main Codec trait
/// Needs to be implemented and provided to FuelBehaviour
pub trait NetworkCodec:
    GossipsubCodec<
        RequestMessage = GossipsubBroadcastRequest,
        ResponseMessage = GossipsubMessage,
    > + RequestResponseCodec<Request = RequestMessage, Response = NetworkResponse>
    + RequestResponseConverter<
        NetworkResponse = NetworkResponse,
        OutboundResponse = OutboundResponse,
        ResponseMessage = ResponseMessage,
    > + Clone
    + Send
    + 'static
{
    /// Returns RequestResponse's Protocol
    /// Needed for initialization of RequestResponse Behaviour
    fn get_req_res_protocol(&self) -> <Self as RequestResponseCodec>::Protocol;
}