sui_network/discovery/
server.rsuse super::{Discovery, SignedNodeInfo, State, MAX_PEERS_TO_SEND};
use anemo::{Request, Response};
use rand::seq::IteratorRandom;
use serde::{Deserialize, Serialize};
use std::{
collections::HashMap,
sync::{Arc, RwLock},
};
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct GetKnownPeersResponseV2 {
pub own_info: SignedNodeInfo,
pub known_peers: Vec<SignedNodeInfo>,
}
pub(super) struct Server {
pub(super) state: Arc<RwLock<State>>,
}
#[anemo::async_trait]
impl Discovery for Server {
async fn get_known_peers_v2(
&self,
_request: Request<()>,
) -> Result<Response<GetKnownPeersResponseV2>, anemo::rpc::Status> {
let state = self.state.read().unwrap();
let own_info = state
.our_info
.clone()
.ok_or_else(|| anemo::rpc::Status::internal("own_info has not been initialized yet"))?;
let known_peers = if state.known_peers.len() < MAX_PEERS_TO_SEND {
state
.known_peers
.values()
.map(|e| e.inner())
.cloned()
.collect()
} else {
let mut rng = rand::thread_rng();
let mut known_peers = state
.connected_peers
.keys()
.filter_map(|peer_id| state.known_peers.get(peer_id))
.map(|info| (info.peer_id, info))
.choose_multiple(&mut rng, MAX_PEERS_TO_SEND)
.into_iter()
.collect::<HashMap<_, _>>();
if known_peers.len() <= MAX_PEERS_TO_SEND {
for info in state
.known_peers
.values()
.choose_multiple(&mut rng, MAX_PEERS_TO_SEND)
{
if known_peers.len() >= MAX_PEERS_TO_SEND {
break;
}
known_peers.insert(info.peer_id, info);
}
}
known_peers
.into_values()
.map(|e| e.inner())
.cloned()
.collect()
};
Ok(Response::new(GetKnownPeersResponseV2 {
own_info,
known_peers,
}))
}
}