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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//! Managing the validator connections in sessions using the gossip network.
use std::fmt::Display;

use futures::channel::mpsc;
use parity_scale_codec::{Decode, Encode};

use crate::{
    crypto::{AuthorityPen, AuthorityVerifier, Signature},
    network::{
        data::{
            component::{Sender, SimpleNetwork},
            SendError,
        },
        AddressingInformation, Data,
    },
    NodeIndex, Recipient, SessionId,
};

mod compatibility;
mod connections;
mod data;
mod discovery;
mod handler;
mod manager;
mod service;

pub use compatibility::{DiscoveryMessage, VersionedAuthentication};
use connections::Connections;
#[cfg(test)]
pub use data::DataInSession;
pub use discovery::Discovery;
#[cfg(test)]
pub use handler::tests::authentication;
pub use handler::{Handler as SessionHandler, HandlerError as SessionHandlerError};
pub use service::{Config as ConnectionManagerConfig, Service as ConnectionManager};
#[allow(unused_imports)]
pub use service::ManagerError;
/// Data validators use to authenticate themselves for a single session
/// and disseminate their addresses.
#[derive(Clone, Debug, PartialEq, Eq, Hash, Encode, Decode)]
pub struct AuthData<A: AddressingInformation> {
    address: A,
    node_id: NodeIndex,
    session_id: SessionId,
}

impl<A: AddressingInformation> AuthData<A> {
    pub fn session(&self) -> SessionId {
        self.session_id
    }

    pub fn creator(&self) -> NodeIndex {
        self.node_id
    }

    pub fn address(&self) -> A {
        self.address.clone()
    }
}

/// A full authentication, consisting of a signed AuthData.
#[derive(Clone, Decode, Encode, Debug, Eq, PartialEq, Hash)]
pub struct Authentication<A: AddressingInformation>(AuthData<A>, Signature);

/// Sends data within a single session.
#[derive(Clone)]
pub struct SessionSender<D: Data> {
    session_id: SessionId,
    messages_for_network: mpsc::UnboundedSender<(D, SessionId, Recipient)>,
}

impl<D: Data> Sender<D> for SessionSender<D> {
    fn send(&self, data: D, recipient: Recipient) -> Result<(), SendError> {
        self.messages_for_network
            .unbounded_send((data, self.session_id, recipient))
            .map_err(|_| SendError::SendFailed)
    }
}

/// Sends and receives data within a single session.
type Network<D> = SimpleNetwork<D, mpsc::UnboundedReceiver<D>, SessionSender<D>>;

/// An interface for managing session networks for validators and nonvalidators.
#[async_trait::async_trait]
pub trait SessionManager<D: Data>: Send + Sync + 'static {
    type Error: Display;

    /// Start participating or update the verifier in the given session where you are not a
    /// validator.
    fn start_nonvalidator_session(
        &self,
        session_id: SessionId,
        verifier: AuthorityVerifier,
    ) -> Result<(), Self::Error>;

    /// Start participating or update the information about the given session where you are a
    /// validator. Returns a session network to be used for sending and receiving data within the
    /// session.
    async fn start_validator_session(
        &self,
        session_id: SessionId,
        verifier: AuthorityVerifier,
        node_id: NodeIndex,
        pen: AuthorityPen,
    ) -> Result<Network<D>, Self::Error>;

    /// Start participating or update the information about the given session where you are a
    /// validator. Used for early starts when you don't yet need the returned network, but would
    /// like to start discovery.
    fn early_start_validator_session(
        &self,
        session_id: SessionId,
        verifier: AuthorityVerifier,
        node_id: NodeIndex,
        pen: AuthorityPen,
    ) -> Result<(), Self::Error>;

    /// Stop participating in the given session.
    fn stop_session(&self, session_id: SessionId) -> Result<(), Self::Error>;
}