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
// Copyright 2020-2021 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

//! # Stronghold Communication
//!
//! This crate enables strongholds on different devices and in different networks to communicate with each other.
//! The main basis for its functionality is the [`libp2p`] crate, which is a system of protocols, specifications
//! and libraries that enable the development of peer-to-peer network applications
//!
//! The library provides two options to use communication, either directly with the [`P2PNetworkBehaviour`],
//! or by using the [`CommunicationActor`] within a [`ActorSystem`].
//!
//! ## P2PNetworkBehaviour
//!
//! The P2pNetworkBehaviour implements the [`NetworkBehaviour`] by combining multiple protocols of Libp2p:
//! - Multiplexing following the [Yamux specification](https://!github.com/hashicorp/yamux/blob/master/spec.md)
//! - Noise: Encryption of the communication using the [Noise protocol](https://!noiseprotocol.org/noise.html) with
//!   XX-Handshake
//! - Multicast DNS: Enable Peer Discovery in a local network
//! - Identify Protocol: Receive identifying information like the `PeerId` and listening addresses when connecting to a
//!   new peer.
//! - Request-Response Protocol: Allows sending direct request/response messages between Peers; it expects a response
//!   for each request
//!  
//! Upon creating a new instance, a transport is created and upgraded, and combined with the P2PNetworkBehaviour into
//! a [`ExpandedSwarm`].
//! This Swarm is returned to the caller and serves as entry-point for all communication to other peers.
//! Additional to the Libp2p methods of the [`ExpandedSwarm`], it enables sending outbound messages, and manages the
//! known peers. Incoming [`P2PEvents`] can be handled by polling from the swarm, e.g. via the [`next`] method.
//!
//! ### Example
//! ```no_run
//! use async_std::task;
//! use communication::behaviour::{BehaviourConfig, P2PNetworkBehaviour};
//! use libp2p::identity::Keypair;
//! use serde::{Deserialize, Serialize};
//!
//! #[derive(Debug, Clone, Serialize, Deserialize)]
//! pub enum Request {
//!     Ping,
//! }
//!
//! #[derive(Debug, Clone, Serialize, Deserialize)]
//! pub enum Response {
//!     Pong,
//! }
//!
//! let local_keys = Keypair::generate_ed25519();
//! let config = BehaviourConfig::default();
//! let mut swarm = task::block_on(P2PNetworkBehaviour::<Request, Response>::init_swarm(local_keys, config))
//!     .expect("Init swarm failed.");
//! ```
//!
//! ## CommunicationActor
//!
//! The [`CommunicationActor`] is using the [`riker`] crate to implement the actor pattern.  
//! When creating a new [`CommunicationActor`], the actor creates a [`P2PNetworkBehaviour`] and continuously polls for
//! events, incoming requests are sent to the client actor that has to be provided in the [`CommunicationConfig`].
//!
//! All swarm interaction, and configuration of the [`CommunicationActor`] is accomplished by sending the appropriate
//! [`CommunicationRequest`] to it, for each [`CommunicationRequest`] a [`CommunicationResults`] is returned to the
//! sender, this also allows using the [ask pattern](https://!riker.rs/patterns/#ask).
//!
//! ### Firewall
//! The communication actor implements a firewall that checks the permission of each outgoing and incoming requests and
//! drops them if the necessary permission has not been set. The required [`ToPermissionVariants`] trait for messages
//! can be derived with the [`communication-macros`], this allows in case of enum Request
//! types to accept specific variants while rejecting others.

pub mod actor;
pub mod behaviour;
pub mod libp2p {
    //! Re-export [`libp2p`] types.
    pub use libp2p::{
        core::{
            connection::ConnectionLimit, identity::Keypair, multiaddr::Protocol, ConnectedPoint, Multiaddr, PeerId,
        },
        swarm::{Swarm, SwarmEvent},
    };
}