cuprated/rpc/request/
address_book.rs1use std::convert::Infallible;
4
5use anyhow::{anyhow, Error};
6use tower::ServiceExt;
7
8use cuprate_helper::cast::usize_to_u64;
9use cuprate_p2p_core::{
10 services::{AddressBookRequest, AddressBookResponse},
11 types::{BanState, ConnectionId},
12 AddressBook, NetworkZone,
13};
14use cuprate_pruning::PruningSeed;
15use cuprate_rpc_types::misc::{ConnectionInfo, Span};
16
17use crate::rpc::constants::FIELD_NOT_SUPPORTED;
18
19pub(crate) async fn peerlist_size<Z: NetworkZone>(
23 address_book: &mut impl AddressBook<Z>,
24) -> Result<(u64, u64), Error> {
25 let AddressBookResponse::PeerlistSize { white, grey } = address_book
26 .ready()
27 .await
28 .map_err(|e| anyhow!(e))?
29 .call(AddressBookRequest::PeerlistSize)
30 .await
31 .map_err(|e| anyhow!(e))?
32 else {
33 unreachable!();
34 };
35
36 Ok((usize_to_u64(white), usize_to_u64(grey)))
37}
38
39pub(crate) async fn connection_info<Z: NetworkZone>(
41 address_book: &mut impl AddressBook<Z>,
42) -> Result<Vec<ConnectionInfo>, Error> {
43 let AddressBookResponse::ConnectionInfo(vec) = address_book
44 .ready()
45 .await
46 .map_err(|e| anyhow!(e))?
47 .call(AddressBookRequest::ConnectionInfo)
48 .await
49 .map_err(|e| anyhow!(e))?
50 else {
51 unreachable!();
52 };
53
54 let vec = vec
56 .into_iter()
57 .map(|info| {
58 let (ip, port) = match info.socket_addr {
59 Some(socket) => (socket.ip().to_string(), socket.port().to_string()),
60 None => (String::new(), String::new()),
61 };
62
63 ConnectionInfo {
64 address: info.address.to_string(),
65 address_type: info.address_type,
66 avg_download: info.avg_download,
67 avg_upload: info.avg_upload,
68 connection_id: String::from(ConnectionId::DEFAULT_STR),
69 current_download: info.current_download,
70 current_upload: info.current_upload,
71 height: info.height,
72 host: info.host,
73 incoming: info.incoming,
74 ip,
75 live_time: info.live_time,
76 localhost: info.localhost,
77 local_ip: info.local_ip,
78 peer_id: hex::encode(info.peer_id.to_ne_bytes()),
79 port,
80 pruning_seed: info.pruning_seed.compress(),
81 recv_count: info.recv_count,
82 recv_idle_time: info.recv_idle_time,
83 rpc_credits_per_hash: info.rpc_credits_per_hash,
84 rpc_port: info.rpc_port,
85 send_count: info.send_count,
86 send_idle_time: info.send_idle_time,
87 state: info.state,
88 support_flags: info.support_flags,
89 }
90 })
91 .collect();
92
93 Ok(vec)
94}
95
96pub(crate) async fn connection_count<Z: NetworkZone>(
98 address_book: &mut impl AddressBook<Z>,
99) -> Result<(u64, u64), Error> {
100 let AddressBookResponse::ConnectionCount { incoming, outgoing } = address_book
101 .ready()
102 .await
103 .map_err(|e| anyhow!(e))?
104 .call(AddressBookRequest::ConnectionCount)
105 .await
106 .map_err(|e| anyhow!(e))?
107 else {
108 unreachable!();
109 };
110
111 Ok((usize_to_u64(incoming), usize_to_u64(outgoing)))
112}
113
114pub(crate) async fn set_ban<Z: NetworkZone>(
116 address_book: &mut impl AddressBook<Z>,
117 set_ban: cuprate_p2p_core::types::SetBan<Z::Addr>,
118) -> Result<(), Error> {
119 let AddressBookResponse::Ok = address_book
120 .ready()
121 .await
122 .map_err(|e| anyhow!(e))?
123 .call(AddressBookRequest::SetBan(set_ban))
124 .await
125 .map_err(|e| anyhow!(e))?
126 else {
127 unreachable!();
128 };
129
130 Ok(())
131}
132
133pub(crate) async fn get_ban<Z: NetworkZone>(
135 address_book: &mut impl AddressBook<Z>,
136 peer: Z::Addr,
137) -> Result<Option<std::time::Instant>, Error> {
138 let AddressBookResponse::GetBan { unban_instant } = address_book
139 .ready()
140 .await
141 .map_err(|e| anyhow!(e))?
142 .call(AddressBookRequest::GetBan(peer))
143 .await
144 .map_err(|e| anyhow!(e))?
145 else {
146 unreachable!();
147 };
148
149 Ok(unban_instant)
150}
151
152pub(crate) async fn get_bans<Z: NetworkZone>(
154 address_book: &mut impl AddressBook<Z>,
155) -> Result<Vec<BanState<Z::Addr>>, Error> {
156 let AddressBookResponse::GetBans(bans) = address_book
157 .ready()
158 .await
159 .map_err(|e| anyhow!(e))?
160 .call(AddressBookRequest::GetBans)
161 .await
162 .map_err(|e| anyhow!(e))?
163 else {
164 unreachable!();
165 };
166
167 Ok(bans)
168}