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
// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0

use crate::application::{
    storage::PeerMetadataStorage,
    types::{PeerError, PeerInfo, PeerState},
};
use async_trait::async_trait;
use diem_types::PeerId;
use std::collections::{hash_map::Entry, HashMap};

/// A generic `NetworkInterface` for applications to connect to networking
///
/// Each application would implement their own `NetworkInterface`.  This would hold `AppData` specific
/// to the application as well as a specific `Sender` for cloning across threads and sending requests.
#[async_trait]
pub trait NetworkInterface {
    type Sender;
    type AppData;

    /// Provides the `PeerMetadataStorage` for other functions.  Not expected to be used externally.
    fn peer_metadata_storage(&self) -> &PeerMetadataStorage;

    /// Give a copy of the sender for the network
    fn sender(&self) -> Self::Sender;

    /// Retrieve only connected peers
    fn connected_peers(&self) -> HashMap<PeerId, PeerInfo> {
        self.filtered_peers(|(_, peer_info)| peer_info.status == PeerState::Connected)
    }

    /// Filter peers with according `filter`
    fn filtered_peers<F: FnMut(&(&PeerId, &PeerInfo)) -> bool>(
        &self,
        filter: F,
    ) -> HashMap<PeerId, PeerInfo> {
        self.peer_metadata_storage().read_filtered(filter)
    }

    /// Retrieve PeerInfo for the node
    fn peers(&self) -> HashMap<PeerId, PeerInfo> {
        self.peer_metadata_storage().read_all()
    }

    /// Insert application specific data
    fn insert_app_data(&self, peer_id: PeerId, data: Self::AppData);

    /// Removes application specific data
    fn remove_app_data(&self, peer_id: &PeerId);

    /// Read application specific data
    fn read_app_data(&self, peer_id: &PeerId) -> Option<Self::AppData>;

    /// Write application specific data, allows for read before write operations
    fn write_app_data<F: FnOnce(&mut Entry<PeerId, Self::AppData>) -> Result<(), PeerError>>(
        &self,
        peer_id: PeerId,
        modifier: F,
    ) -> Result<(), PeerError>;
}