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}