sequencer/request_response/
mod.rs

1use std::future::Future;
2
3use data_source::DataSource;
4use derive_more::derive::Deref;
5use espresso_types::{traits::SequencerPersistence, PubKey, SeqTypes};
6use hotshot::{traits::NodeImplementation, types::BLSPrivKey};
7use hotshot_types::traits::{network::ConnectedNetwork, node_implementation::Versions};
8use network::Sender;
9use recipient_source::RecipientSource;
10use request::{Request, Response};
11use request_response::{
12    network::Bytes, RequestError, RequestResponse, RequestResponseConfig, RequestType,
13};
14use tokio::sync::mpsc::Receiver;
15
16pub mod catchup;
17pub mod data_source;
18pub mod network;
19pub mod recipient_source;
20pub mod request;
21
22/// A concrete type wrapper around `RequestResponse`. We need this so that we can implement
23/// local traits like `StateCatchup`. It also helps with readability.
24#[derive(Clone, Deref)]
25pub struct RequestResponseProtocol<
26    I: NodeImplementation<SeqTypes>,
27    V: Versions,
28    N: ConnectedNetwork<PubKey>,
29    P: SequencerPersistence,
30> {
31    #[deref]
32    #[allow(clippy::type_complexity)]
33    /// The actual inner request response protocol
34    inner: RequestResponse<
35        Sender,
36        Receiver<Bytes>,
37        Request,
38        RecipientSource<I, V>,
39        DataSource<I, V, N, P>,
40        PubKey,
41    >,
42
43    /// The configuration we used for the above inner protocol. This is nice to have for
44    /// estimating when we should make another request
45    config: RequestResponseConfig,
46
47    /// The public key of this node
48    public_key: PubKey,
49    /// The private key of this node
50    private_key: BLSPrivKey,
51}
52
53impl<
54        I: NodeImplementation<SeqTypes>,
55        V: Versions,
56        N: ConnectedNetwork<PubKey>,
57        P: SequencerPersistence,
58    > RequestResponseProtocol<I, V, N, P>
59{
60    /// Create a new RequestResponseProtocol from the inner
61    pub fn new(
62        // The configuration for the protocol
63        config: RequestResponseConfig,
64        // The network sender that [`RequestResponseProtocol`] will use to send messages
65        sender: Sender,
66        // The network receiver that [`RequestResponseProtocol`] will use to receive messages
67        receiver: Receiver<Bytes>,
68        // The recipient source that [`RequestResponseProtocol`] will use to get the recipients
69        // that a specific message should expect responses from
70        recipient_source: RecipientSource<I, V>,
71        // The [response] data source that [`RequestResponseProtocol`] will use to derive the
72        // response data for a specific request
73        data_source: DataSource<I, V, N, P>,
74        // The public key of this node
75        public_key: PubKey,
76        // The private key of this node
77        private_key: BLSPrivKey,
78    ) -> Self {
79        Self {
80            inner: RequestResponse::new(
81                config.clone(),
82                sender,
83                receiver,
84                recipient_source,
85                data_source,
86            ),
87            config,
88            public_key,
89            private_key,
90        }
91    }
92}
93
94impl<
95        I: NodeImplementation<SeqTypes>,
96        V: Versions,
97        N: ConnectedNetwork<PubKey>,
98        P: SequencerPersistence,
99    > RequestResponseProtocol<I, V, N, P>
100{
101    pub async fn request_indefinitely<F, Fut, O>(
102        &self,
103        // The request to make
104        request: Request,
105        // The type of request
106        request_type: RequestType,
107        // The response validation function
108        response_validation_fn: F,
109    ) -> std::result::Result<O, RequestError>
110    where
111        F: Fn(&Request, Response) -> Fut + Send + Sync + 'static + Clone,
112        Fut: Future<Output = anyhow::Result<O>> + Send + Sync + 'static,
113        O: Send + Sync + 'static + Clone,
114    {
115        // Request from the inner protocol
116        self.inner
117            .request_indefinitely(
118                &self.public_key,
119                &self.private_key,
120                request_type,
121                self.config.incoming_request_ttl,
122                request,
123                response_validation_fn,
124            )
125            .await
126    }
127}