Skip to main content

ossa_core/network/protocol/
mod.rs

1use bytes::Bytes;
2use futures::{SinkExt, StreamExt};
3use serde::{Deserialize, Serialize};
4use serde_cbor::to_vec;
5use std::any::type_name;
6use std::collections::BTreeSet;
7use std::fmt::Debug;
8use std::future::Future;
9use std::marker::Send;
10use tokio::net::TcpStream;
11use tokio::sync::watch;
12use tokio_util::{
13    codec::{self, LengthDelimitedCodec},
14    sync::PollSendError,
15};
16use tracing::{debug, error, info, trace};
17
18use crate::protocol::v0::{
19    MsgStoreMetadataHeader, StoreMetadataHeaderRequest, StoreMetadataHeaderResponse,
20};
21use crate::protocol::Version;
22use crate::store::v0::MetadataHeader;
23use crate::util::Stream;
24use crate::{
25    auth::DeviceId,
26    core::{OssaType, StoreStatuses},
27    network::multiplexer,
28};
29
30pub mod ecg_sync;
31pub mod keep_alive;
32
33pub(crate) trait MiniProtocol: Send {
34    type Message: Serialize + for<'a> Deserialize<'a> + Send;
35
36    // fn run_client<S: Stream<Self::Message>, O: OssaType>(self, stream: S, active_stores: watch::Receiver<StoreStatuses<O::StoreId>>,) -> impl Future<Output = ()> + Send;
37    // fn run_server<S: Stream<Self::Message>, O: OssaType>(self, stream: S, active_stores: watch::Receiver<StoreStatuses<O::StoreId>>,) -> impl Future<Output = ()> + Send;
38    fn run_client<S: Stream<Self::Message>>(self, stream: S) -> impl Future<Output = ()> + Send;
39    fn run_server<S: Stream<Self::Message>>(self, stream: S) -> impl Future<Output = ()> + Send;
40}
41
42// pub enum ProtocolVersion {
43//     V0,
44// }
45
46type MsgHandshake = DeviceId;
47
48pub(crate) struct HandshakeInfo {
49    version: Version,
50    peer_id: DeviceId,
51}
52
53pub(crate) enum HandshakeError {
54    ConnectingToSelf,
55}
56
57impl HandshakeInfo {
58    pub(crate) fn version(&self) -> Version {
59        self.version
60    }
61
62    pub(crate) fn peer_id(&self) -> DeviceId {
63        self.peer_id
64    }
65}
66
67// TODO: Actually setup TLS connection and get their DeviceId.
68pub(crate) async fn run_handshake_server<S: Stream<MsgHandshake>>(
69    stream: &mut S,
70    device_id: &DeviceId,
71) -> Result<HandshakeInfo, HandshakeError> {
72    // TODO: Implement this and make it abstract.
73
74    // Get their DeviceId.
75    let peer_id = receive(stream).await.expect("TODO");
76
77    // Send our DeviceId.
78    send(stream, *device_id).await.expect("TODO");
79
80    // Check that the peer isn't us.
81    if device_id == &peer_id {
82        return Err(HandshakeError::ConnectingToSelf);
83    }
84
85    Ok(HandshakeInfo {
86        peer_id,
87        version: Version::V0,
88    })
89}
90
91pub(crate) async fn run_handshake_client<S: Stream<MsgHandshake>>(
92    stream: &mut S,
93    device_id: &DeviceId,
94) -> Result<HandshakeInfo, HandshakeError> {
95    // TODO: Implement this and make it abstract.
96
97    // Send our DeviceId.
98    send(stream, *device_id).await.expect("TODO");
99
100    // Get their DeviceId.
101    let peer_id = receive(stream).await.expect("TODO");
102
103    // Check that the peer isn't us.
104    if device_id == &peer_id {
105        return Err(HandshakeError::ConnectingToSelf);
106    }
107
108    Ok(HandshakeInfo {
109        peer_id,
110        version: Version::V0,
111    })
112}
113
114// TODO: Generalize the argument.
115// pub(crate) async fn run_store_metadata_server<'a, StoreId:Deserialize<'a>>(stream: &mut codec::Framed<TcpStream, LengthDelimitedCodec>) -> () {
116pub(crate) async fn run_store_metadata_server<StoreId, S: Stream<MsgStoreMetadataHeader<StoreId>>>(
117    stream: &mut S,
118) -> Result<(), ProtocolError>
119where
120    StoreId: for<'a> Deserialize<'a> + Send + Debug,
121{
122    let req: StoreMetadataHeaderRequest<StoreId> = receive(stream).await?;
123    info!("Received request: {:?}", req);
124
125    // TODO: Proper response.
126    let response: StoreMetadataHeaderResponse<StoreId> = StoreMetadataHeaderResponse {
127        header: MetadataHeader {
128            nonce: [0; 32],
129            protocol_version: Version::V0,
130            store_type: todo!(), // [1;32],
131            initial_state_size: 0,
132            merkle_root: todo!(), // [2;32],
133        },
134        // body: None,
135    };
136
137    send(stream, response).await
138}
139
140// pub async fn run_store_metadata_client<TypeId, StoreId, S:Stream<MsgStoreMetadataHeader<TypeId, StoreId>>>(stream: &mut codec::Framed<TcpStream, LengthDelimitedCodec>, request: &StoreMetadataHeaderRequest<StoreId>) -> Result<StoreMetadataHeaderResponse<TypeId, StoreId>, ProtocolError>
141pub async fn run_store_metadata_client<StoreId, S: Stream<MsgStoreMetadataHeader<StoreId>>>(
142    stream: &mut S,
143    request: StoreMetadataHeaderRequest<StoreId>,
144) -> Result<StoreMetadataHeaderResponse<StoreId>, ProtocolError>
145where
146    StoreId: Serialize + for<'a> Deserialize<'a> + Debug,
147{
148    send(stream, request).await?;
149
150    receive(stream).await
151}
152
153#[derive(Debug)]
154pub enum ProtocolError {
155    SerializationError(serde_cbor::Error),
156    DeserializationError(serde_cbor::Error),
157    ReceivedNoData, // Connection closed?
158    StreamSendError(std::io::Error),
159    StreamReceiveError(std::io::Error),
160    ProtocolDeviation, // Temporary?
161    ChannelSendError(PollSendError<(multiplexer::StreamId, Bytes)>),
162}
163
164/// Send a message over the given stream.
165pub(crate) async fn send<S, T, U>(stream: &mut S, message: T) -> Result<(), ProtocolError>
166where
167    S: Stream<U>,
168    T: Into<U>,
169{
170    match stream.send(message.into()).await {
171        Err(err) => {
172            // TODO: Push the error up the stack instead of recording it here?
173            error!("Failed to send {}: {:?}", type_name::<T>(), err);
174            Err(err)
175        }
176        Ok(()) => Ok(()),
177    }
178}
179
180/// Receive a message from the given stream.
181pub(crate) async fn receive<S, T, U>(stream: &mut S) -> Result<U, ProtocolError>
182where
183    S: Stream<T>,
184    U: Debug,
185    T: TryInto<U>,
186{
187    match stream.next().await {
188        None => {
189            error!("Failed to receive data from peer"); // Closed connection?
190            Err(ProtocolError::ReceivedNoData)
191        }
192        Some(Err(err)) => {
193            error!("Error while receiving data from peer: {:?}", err);
194            Err(err)
195        }
196        Some(Ok(msg)) => {
197            match msg.try_into() {
198                Err(err) => {
199                    error!("Received unexpected data from peer"); // : {:?}", err);
200                    Err(ProtocolError::ProtocolDeviation)
201                }
202                Ok(msg) => {
203                    trace!("Received data from peer: {:?}", msg);
204                    Ok(msg)
205                }
206            }
207        }
208    }
209}