sc_authority_discovery/service.rs
1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
5
6// This program is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with this program. If not, see <https://www.gnu.org/licenses/>.
18
19use std::{collections::HashSet, fmt::Debug};
20
21use crate::ServicetoWorkerMsg;
22
23use futures::{
24 channel::{mpsc, oneshot},
25 SinkExt,
26};
27
28use sc_network::Multiaddr;
29use sc_network_types::PeerId;
30use sp_authority_discovery::AuthorityId;
31
32/// Service to interact with the [`crate::Worker`].
33#[derive(Clone)]
34pub struct Service {
35 to_worker: mpsc::Sender<ServicetoWorkerMsg>,
36}
37
38impl Debug for Service {
39 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
40 f.debug_tuple("AuthorityDiscoveryService").finish()
41 }
42}
43
44/// A [`Service`] allows to interact with a [`crate::Worker`], e.g. by querying the
45/// [`crate::Worker`]'s local address cache for a given [`AuthorityId`].
46impl Service {
47 pub(crate) fn new(to_worker: mpsc::Sender<ServicetoWorkerMsg>) -> Self {
48 Self { to_worker }
49 }
50
51 /// Get the addresses for the given [`AuthorityId`] from the local address
52 /// cache.
53 ///
54 /// Returns `None` if no entry was present or connection to the
55 /// [`crate::Worker`] failed.
56 ///
57 /// Note: [`Multiaddr`]s returned always include a [`PeerId`] via a
58 /// [`sc_network_types::multiaddr::Protocol::P2p`] component. Equality of
59 /// [`PeerId`]s across [`Multiaddr`]s returned by a single call is not
60 /// enforced today, given that there are still authorities out there
61 /// publishing the addresses of their sentry nodes on the DHT. In the future
62 /// this guarantee can be provided.
63 pub async fn get_addresses_by_authority_id(
64 &mut self,
65 authority: AuthorityId,
66 ) -> Option<HashSet<Multiaddr>> {
67 let (tx, rx) = oneshot::channel();
68
69 self.to_worker
70 .send(ServicetoWorkerMsg::GetAddressesByAuthorityId(authority, tx))
71 .await
72 .ok()?;
73
74 rx.await.ok().flatten()
75 }
76
77 /// Get the [`AuthorityId`] for the given [`PeerId`] from the local address
78 /// cache.
79 ///
80 /// Returns `None` if no entry was present or connection to the
81 /// [`crate::Worker`] failed.
82 pub async fn get_authority_ids_by_peer_id(
83 &mut self,
84 peer_id: PeerId,
85 ) -> Option<HashSet<AuthorityId>> {
86 let (tx, rx) = oneshot::channel();
87
88 self.to_worker
89 .send(ServicetoWorkerMsg::GetAuthorityIdsByPeerId(peer_id, tx))
90 .await
91 .ok()?;
92
93 rx.await.ok().flatten()
94 }
95}