litep2p/protocol/libp2p/ping/
config.rs

1// Copyright 2023 litep2p developers
2//
3// Permission is hereby granted, free of charge, to any person obtaining a
4// copy of this software and associated documentation files (the "Software"),
5// to deal in the Software without restriction, including without limitation
6// the rights to use, copy, modify, merge, publish, distribute, sublicense,
7// and/or sell copies of the Software, and to permit persons to whom the
8// Software is furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in
11// all copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
14// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19// DEALINGS IN THE SOFTWARE.
20
21use crate::{
22    codec::ProtocolCodec, protocol::libp2p::ping::PingEvent, types::protocol::ProtocolName,
23    DEFAULT_CHANNEL_SIZE,
24};
25
26use futures::Stream;
27use tokio::sync::mpsc::{channel, Sender};
28use tokio_stream::wrappers::ReceiverStream;
29
30/// IPFS Ping protocol name as a string.
31pub const PROTOCOL_NAME: &str = "/ipfs/ping/1.0.0";
32
33/// Size for `/ipfs/ping/1.0.0` payloads.
34const PING_PAYLOAD_SIZE: usize = 32;
35
36/// Maximum PING failures.
37const MAX_FAILURES: usize = 3;
38
39/// Ping configuration.
40pub struct Config {
41    /// Protocol name.
42    pub(crate) protocol: ProtocolName,
43
44    /// Codec used by the protocol.
45    pub(crate) codec: ProtocolCodec,
46
47    /// Maximum failures before the peer is considered unreachable.
48    pub(crate) max_failures: usize,
49
50    /// TX channel for sending events to the user protocol.
51    pub(crate) tx_event: Sender<PingEvent>,
52}
53
54impl Config {
55    /// Create new [`Config`] with default values.
56    ///
57    /// Returns a config that is given to `Litep2pConfig` and an event stream for [`PingEvent`]s.
58    pub fn default() -> (Self, Box<dyn Stream<Item = PingEvent> + Send + Unpin>) {
59        let (tx_event, rx_event) = channel(DEFAULT_CHANNEL_SIZE);
60
61        (
62            Self {
63                tx_event,
64                max_failures: MAX_FAILURES,
65                protocol: ProtocolName::from(PROTOCOL_NAME),
66                codec: ProtocolCodec::Identity(PING_PAYLOAD_SIZE),
67            },
68            Box::new(ReceiverStream::new(rx_event)),
69        )
70    }
71}
72
73/// Ping configuration builder.
74pub struct ConfigBuilder {
75    /// Protocol name.
76    protocol: ProtocolName,
77
78    /// Codec used by the protocol.
79    codec: ProtocolCodec,
80
81    /// Maximum failures before the peer is considered unreachable.
82    max_failures: usize,
83}
84
85impl Default for ConfigBuilder {
86    fn default() -> Self {
87        Self::new()
88    }
89}
90
91impl ConfigBuilder {
92    /// Create new default [`Config`] which can be modified by the user.
93    pub fn new() -> Self {
94        Self {
95            max_failures: MAX_FAILURES,
96            protocol: ProtocolName::from(PROTOCOL_NAME),
97            codec: ProtocolCodec::Identity(PING_PAYLOAD_SIZE),
98        }
99    }
100
101    /// Set maximum failures the protocol.
102    pub fn with_max_failure(mut self, max_failures: usize) -> Self {
103        self.max_failures = max_failures;
104        self
105    }
106
107    /// Build [`Config`].
108    pub fn build(self) -> (Config, Box<dyn Stream<Item = PingEvent> + Send + Unpin>) {
109        let (tx_event, rx_event) = channel(DEFAULT_CHANNEL_SIZE);
110
111        (
112            Config {
113                tx_event,
114                max_failures: self.max_failures,
115                protocol: self.protocol,
116                codec: self.codec,
117            },
118            Box::new(ReceiverStream::new(rx_event)),
119        )
120    }
121}