hopr_transport_p2p/
lib.rs1pub mod constants;
26
27pub mod errors;
29
30pub mod swarm;
32
33mod behavior;
35
36use std::collections::HashSet;
37
38use futures::{AsyncRead, AsyncWrite};
39pub use hopr_api::network::{Health, Observable};
40use hopr_api::network::{NetworkObservations, NetworkView};
41use hopr_transport_network::observation::Observations;
42use libp2p::{Multiaddr, PeerId};
43
44pub use crate::{
45 behavior::{HoprNetworkBehavior, HoprNetworkBehaviorEvent},
46 swarm::HoprLibp2pNetworkBuilder,
47};
48
49#[derive(Clone)]
50pub struct HoprNetwork {
51 tracker: hopr_transport_network::track::NetworkPeerTracker,
52 store: hopr_transport_network::store::NetworkPeerStore,
53 control: libp2p_stream::Control,
54 protocol: libp2p::StreamProtocol,
55}
56
57impl std::fmt::Debug for HoprNetwork {
58 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59 f.debug_struct("HoprNetwork")
60 .field("tracker", &self.tracker)
61 .field("store", &self.store)
62 .field("protocol", &self.protocol)
63 .finish()
64 }
65}
66
67impl NetworkView for HoprNetwork {
68 fn listening_as(&self) -> HashSet<Multiaddr> {
69 self.store.get(self.store.me()).unwrap_or_else(|| {
70 tracing::error!("failed to get own peer info from the peer store");
71 std::collections::HashSet::new()
72 })
73 }
74
75 #[inline]
76 fn discovered_peers(&self) -> HashSet<PeerId> {
77 self.store.iter_keys().collect()
78 }
79
80 #[inline]
81 fn connected_peers(&self) -> HashSet<PeerId> {
82 self.tracker.iter_keys().collect()
83 }
84
85 #[inline]
86 fn multiaddress_of(&self, peer: &PeerId) -> Option<HashSet<Multiaddr>> {
87 self.store.get(peer)
88 }
89
90 #[allow(refining_impl_trait_reachable)]
91 #[inline]
92 fn observations_for(&self, peer: &PeerId) -> Option<Observations> {
93 self.tracker.get(peer)
94 }
95
96 fn health(&self) -> Health {
97 match self.tracker.len() {
98 0 => Health::Red,
99 1 => Health::Orange,
100 2..4 => Health::Yellow,
101 _ => Health::Green,
102 }
103 }
104}
105
106#[async_trait::async_trait]
107impl hopr_transport_protocol::stream::BidirectionalStreamControl for HoprNetwork {
108 fn accept(
109 mut self,
110 ) -> Result<impl futures::Stream<Item = (PeerId, impl AsyncRead + AsyncWrite + Send)> + Send, impl std::error::Error>
111 {
112 self.control.accept(self.protocol)
113 }
114
115 async fn open(mut self, peer: PeerId) -> Result<impl AsyncRead + AsyncWrite + Send, impl std::error::Error> {
116 self.control.open_stream(peer, self.protocol).await
117 }
118}
119
120impl NetworkObservations for HoprNetwork {
121 fn update(&self, peer: &PeerId, result: std::result::Result<std::time::Duration, ()>) {
122 self.tracker.alter(peer, |_, mut o| {
123 o.record_probe(result.map_err(|_| ()));
124 o
125 });
126 }
127}