Skip to content

Commit 668390a

Browse files
authored
client/authority-discovery: Remove sentry node logic (paritytech#7368)
* client/authority-discovery: Remove sentry node logic The notion of sentry nodes has been deprecated (see [1] for details). This commit removes support for sentry nodes in the `client/authority-discovery` module. While removing `Role::Sentry` this commit also introduces `Role::Discover`, allowing a node to discover addresses of authorities without publishing ones own addresses. This will be needed in Polkadot for collator nodes. [1] paritytech#6845 * client/authority-discovery/service: Improve PeerId comment
1 parent c60f008 commit 668390a

6 files changed

Lines changed: 69 additions & 214 deletions

File tree

bin/node/cli/src/service.rs

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider};
2626
use node_primitives::Block;
2727
use node_runtime::RuntimeApi;
2828
use sc_service::{
29-
config::{Role, Configuration}, error::{Error as ServiceError},
29+
config::{Configuration}, error::{Error as ServiceError},
3030
RpcHandlers, TaskManager,
3131
};
3232
use sp_inherents::InherentDataProviders;
@@ -258,21 +258,10 @@ pub fn new_full_base(
258258
}
259259

260260
// Spawn authority discovery module.
261-
if matches!(role, Role::Authority{..} | Role::Sentry {..}) {
262-
let (sentries, authority_discovery_role) = match role {
263-
sc_service::config::Role::Authority { ref sentry_nodes } => (
264-
sentry_nodes.clone(),
265-
sc_authority_discovery::Role::Authority (
266-
keystore_container.keystore(),
267-
),
268-
),
269-
sc_service::config::Role::Sentry {..} => (
270-
vec![],
271-
sc_authority_discovery::Role::Sentry,
272-
),
273-
_ => unreachable!("Due to outer matches! constraint; qed.")
274-
};
275-
261+
if role.is_authority() {
262+
let authority_discovery_role = sc_authority_discovery::Role::PublishAndDiscover(
263+
keystore_container.keystore(),
264+
);
276265
let dht_event_stream = network.event_stream("authority-discovery")
277266
.filter_map(|e| async move { match e {
278267
Event::Dht(e) => Some(e),
@@ -281,7 +270,6 @@ pub fn new_full_base(
281270
let (authority_discovery_worker, _service) = sc_authority_discovery::new_worker_and_service(
282271
client.clone(),
283272
network.clone(),
284-
sentries,
285273
Box::pin(dht_event_stream),
286274
authority_discovery_role,
287275
prometheus_registry.clone(),

client/authority-discovery/src/lib.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use futures::channel::{mpsc, oneshot};
3232
use futures::Stream;
3333

3434
use sc_client_api::blockchain::HeaderBackend;
35-
use sc_network::{config::MultiaddrWithPeerId, DhtEvent, Multiaddr, PeerId};
35+
use sc_network::{DhtEvent, Multiaddr, PeerId};
3636
use sp_authority_discovery::{AuthorityDiscoveryApi, AuthorityId};
3737
use sp_runtime::traits::Block as BlockT;
3838
use sp_api::ProvideRuntimeApi;
@@ -44,10 +44,11 @@ mod tests;
4444
mod worker;
4545

4646
/// Create a new authority discovery [`Worker`] and [`Service`].
47+
///
48+
/// See the struct documentation of each for more details.
4749
pub fn new_worker_and_service<Client, Network, Block, DhtEventStream>(
4850
client: Arc<Client>,
4951
network: Arc<Network>,
50-
sentry_nodes: Vec<MultiaddrWithPeerId>,
5152
dht_event_rx: DhtEventStream,
5253
role: Role,
5354
prometheus_registry: Option<prometheus_endpoint::Registry>,
@@ -62,7 +63,7 @@ where
6263
let (to_worker, from_service) = mpsc::channel(0);
6364

6465
let worker = Worker::new(
65-
from_service, client, network, sentry_nodes, dht_event_rx, role, prometheus_registry,
66+
from_service, client, network, dht_event_rx, role, prometheus_registry,
6667
);
6768
let service = Service::new(to_worker);
6869

client/authority-discovery/src/service.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,12 @@ impl Service {
4343
/// Returns `None` if no entry was present or connection to the
4444
/// [`crate::Worker`] failed.
4545
///
46-
/// [`Multiaddr`]s returned always include a [`PeerId`] via a
47-
/// [`libp2p::core::multiaddr:Protocol::P2p`] component. [`Multiaddr`]s
48-
/// might differ in their [`PeerId`], e.g. when each [`Multiaddr`]
49-
/// represents a different sentry node. This might change once support for
50-
/// sentry nodes is removed (see
51-
/// https://github.com/paritytech/substrate/issues/6845).
46+
/// Note: [`Multiaddr`]s returned always include a [`PeerId`] via a
47+
/// [`libp2p::core::multiaddr:Protocol::P2p`] component. Equality of
48+
/// [`PeerId`]s across [`Multiaddr`]s returned by a single call is not
49+
/// enforced today, given that there are still authorities out there
50+
/// publishing the addresses of their sentry nodes on the DHT. In the future
51+
/// this guarantee can be provided.
5252
pub async fn get_addresses_by_authority_id(&mut self, authority: AuthorityId) -> Option<Vec<Multiaddr>> {
5353
let (tx, rx) = oneshot::channel();
5454

client/authority-discovery/src/tests.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,8 @@ fn get_addresses_and_authority_id() {
5555
let (mut worker, mut service) = new_worker_and_service(
5656
test_api,
5757
network.clone(),
58-
vec![],
5958
Box::pin(dht_event_rx),
60-
Role::Authority(key_store.into()),
59+
Role::PublishAndDiscover(key_store.into()),
6160
None,
6261
);
6362
worker.inject_addresses(remote_authority_id.clone(), vec![remote_addr.clone()]);

client/authority-discovery/src/worker.rs

Lines changed: 39 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,13 @@ use futures_timer::Delay;
2929
use addr_cache::AddrCache;
3030
use async_trait::async_trait;
3131
use codec::Decode;
32-
use either::Either;
3332
use libp2p::{core::multiaddr, multihash::Multihash};
3433
use log::{debug, error, log_enabled};
3534
use prometheus_endpoint::{Counter, CounterVec, Gauge, Opts, U64, register};
3635
use prost::Message;
3736
use rand::{seq::SliceRandom, thread_rng};
3837
use sc_client_api::blockchain::HeaderBackend;
3938
use sc_network::{
40-
config::MultiaddrWithPeerId,
4139
DhtEvent,
4240
ExHashT,
4341
Multiaddr,
@@ -73,68 +71,47 @@ const MAX_ADDRESSES_PER_AUTHORITY: usize = 10;
7371
/// Maximum number of in-flight DHT lookups at any given point in time.
7472
const MAX_IN_FLIGHT_LOOKUPS: usize = 8;
7573

76-
/// Role an authority discovery module can run as.
74+
/// Role an authority discovery [`Worker`] can run as.
7775
pub enum Role {
78-
/// Actual authority as well as a reference to its key store.
79-
Authority(Arc<dyn CryptoStore>),
80-
/// Sentry node that guards an authority.
81-
///
82-
/// No reference to its key store needed, as sentry nodes don't have an identity to sign
83-
/// addresses with in the first place.
84-
Sentry,
76+
/// Publish own addresses and discover addresses of others.
77+
PublishAndDiscover(Arc<dyn CryptoStore>),
78+
/// Discover addresses of others.
79+
Discover,
8580
}
8681

87-
/// A [`Worker`] makes a given authority discoverable and discovers other
88-
/// authorities.
89-
///
90-
/// The [`Worker`] implements the Future trait. By
91-
/// polling [`Worker`] an authority:
82+
83+
/// An authority discovery [`Worker`] can publish the local node's addresses as well as discover
84+
/// those of other nodes via a Kademlia DHT.
9285
///
93-
/// 1. **Makes itself discoverable**
86+
/// When constructed with [`Role::PublishAndDiscover`] a [`Worker`] will
9487
///
95-
/// 1. Retrieves its external addresses (including peer id) or the ones of
96-
/// its sentry nodes.
88+
/// 1. Retrieve its external addresses (including peer id).
9789
///
98-
/// 2. Signs the above.
90+
/// 2. Get the list of keys owned by the local node participating in the current authority set.
9991
///
100-
/// 3. Puts the signature and the addresses on the libp2p Kademlia DHT.
92+
/// 3. Sign the addresses with the keys.
10193
///
94+
/// 4. Put addresses and signature as a record with the authority id as a key on a Kademlia DHT.
10295
///
103-
/// 2. **Discovers other authorities**
96+
/// When constructed with either [`Role::PublishAndDiscover`] or [`Role::Publish`] a [`Worker`] will
10497
///
105-
/// 1. Retrieves the current and next set of authorities.
98+
/// 1. Retrieve the current and next set of authorities.
10699
///
107-
/// 2. Starts DHT queries for the ids of the authorities.
100+
/// 2. Start DHT queries for the ids of the authorities.
108101
///
109-
/// 3. Validates the signatures of the retrieved key value pairs.
102+
/// 3. Validate the signatures of the retrieved key value pairs.
110103
///
111-
/// 4. Adds the retrieved external addresses as priority nodes to the
112-
/// peerset.
104+
/// 4. Add the retrieved external addresses as priority nodes to the
105+
/// network peerset.
113106
///
114-
/// When run as a sentry node, the [`Worker`] does not publish
115-
/// any addresses to the DHT but still discovers validators and sentry nodes of
116-
/// validators, i.e. only step 2 (Discovers other authorities) is executed.
117-
pub struct Worker<Client, Network, Block, DhtEventStream>
118-
where
119-
Block: BlockT + 'static,
120-
Network: NetworkProvider,
121-
Client: ProvideRuntimeApi<Block> + Send + Sync + 'static + HeaderBackend<Block>,
122-
<Client as ProvideRuntimeApi<Block>>::Api: AuthorityDiscoveryApi<Block>,
123-
{
124-
/// Channel receiver for messages send by an [`Service`].
107+
/// 5. Allow querying of the collected addresses via the [`crate::Service`].
108+
pub struct Worker<Client, Network, Block, DhtEventStream> {
109+
/// Channel receiver for messages send by a [`Service`].
125110
from_service: Fuse<mpsc::Receiver<ServicetoWorkerMsg>>,
126111

127112
client: Arc<Client>,
128113

129114
network: Arc<Network>,
130-
/// List of sentry node public addresses.
131-
//
132-
// There are 3 states:
133-
// - None: No addresses were specified.
134-
// - Some(vec![]): Addresses were specified, but none could be parsed as proper
135-
// Multiaddresses.
136-
// - Some(vec![a, b, c, ...]): Valid addresses were specified.
137-
sentry_nodes: Option<Vec<Multiaddr>>,
138115
/// Channel we receive Dht events on.
139116
dht_event_rx: DhtEventStream,
140117

@@ -169,15 +146,11 @@ where
169146
AuthorityDiscoveryApi<Block, Error = sp_blockchain::Error>,
170147
DhtEventStream: Stream<Item = DhtEvent> + Unpin,
171148
{
172-
/// Return a new [`Worker`].
173-
///
174-
/// Note: When specifying `sentry_nodes` this module will not advertise the public addresses of
175-
/// the node itself but only the public addresses of its sentry nodes.
149+
/// Construct a [`Worker`].
176150
pub(crate) fn new(
177151
from_service: mpsc::Receiver<ServicetoWorkerMsg>,
178152
client: Arc<Client>,
179153
network: Arc<Network>,
180-
sentry_nodes: Vec<MultiaddrWithPeerId>,
181154
dht_event_rx: DhtEventStream,
182155
role: Role,
183156
prometheus_registry: Option<prometheus_endpoint::Registry>,
@@ -207,12 +180,6 @@ where
207180
query_interval_duration,
208181
);
209182

210-
let sentry_nodes = if !sentry_nodes.is_empty() {
211-
Some(sentry_nodes.into_iter().map(|ma| ma.concat()).collect::<Vec<_>>())
212-
} else {
213-
None
214-
};
215-
216183
let addr_cache = AddrCache::new();
217184

218185
let metrics = match prometheus_registry {
@@ -232,7 +199,6 @@ where
232199
from_service: from_service.fuse(),
233200
client,
234201
network,
235-
sentry_nodes,
236202
dht_event_rx,
237203
publish_interval,
238204
query_interval,
@@ -313,33 +279,23 @@ where
313279
}
314280

315281
fn addresses_to_publish(&self) -> impl ExactSizeIterator<Item = Multiaddr> {
316-
match &self.sentry_nodes {
317-
Some(addrs) => Either::Left(addrs.clone().into_iter()),
318-
None => {
319-
let peer_id: Multihash = self.network.local_peer_id().into();
320-
Either::Right(
321-
self.network.external_addresses()
322-
.into_iter()
323-
.map(move |a| {
324-
if a.iter().any(|p| matches!(p, multiaddr::Protocol::P2p(_))) {
325-
a
326-
} else {
327-
a.with(multiaddr::Protocol::P2p(peer_id.clone()))
328-
}
329-
}),
330-
)
331-
}
332-
}
282+
let peer_id: Multihash = self.network.local_peer_id().into();
283+
self.network.external_addresses()
284+
.into_iter()
285+
.map(move |a| {
286+
if a.iter().any(|p| matches!(p, multiaddr::Protocol::P2p(_))) {
287+
a
288+
} else {
289+
a.with(multiaddr::Protocol::P2p(peer_id.clone()))
290+
}
291+
})
333292
}
334293

335-
/// Publish either our own or if specified the public addresses of our sentry nodes.
294+
/// Publish own public addresses.
336295
async fn publish_ext_addresses(&mut self) -> Result<()> {
337296
let key_store = match &self.role {
338-
Role::Authority(key_store) => key_store,
339-
// Only authority nodes can put addresses (their own or the ones of their sentry nodes)
340-
// on the Dht. Sentry nodes don't have a known identity to authenticate such addresses,
341-
// thus `publish_ext_addresses` becomes a no-op.
342-
Role::Sentry => return Ok(()),
297+
Role::PublishAndDiscover(key_store) => key_store,
298+
Role::Discover => return Ok(()),
343299
};
344300

345301
let addresses = self.addresses_to_publish();
@@ -394,12 +350,12 @@ where
394350
let id = BlockId::hash(self.client.info().best_hash);
395351

396352
let local_keys = match &self.role {
397-
Role::Authority(key_store) => {
353+
Role::PublishAndDiscover(key_store) => {
398354
key_store.sr25519_public_keys(
399355
key_types::AUTHORITY_DISCOVERY
400356
).await.into_iter().collect::<HashSet<_>>()
401357
},
402-
Role::Sentry => HashSet::new(),
358+
Role::Discover => HashSet::new(),
403359
};
404360

405361
let mut authorities = self
@@ -798,13 +754,7 @@ impl Metrics {
798754

799755
// Helper functions for unit testing.
800756
#[cfg(test)]
801-
impl<Block, Client, Network, DhtEventStream> Worker<Client, Network, Block, DhtEventStream>
802-
where
803-
Block: BlockT + 'static,
804-
Network: NetworkProvider,
805-
Client: ProvideRuntimeApi<Block> + Send + Sync + 'static + HeaderBackend<Block>,
806-
<Client as ProvideRuntimeApi<Block>>::Api: AuthorityDiscoveryApi<Block>,
807-
{
757+
impl<Block, Client, Network, DhtEventStream> Worker<Client, Network, Block, DhtEventStream> {
808758
pub(crate) fn inject_addresses(&mut self, authority: AuthorityId, addresses: Vec<Multiaddr>) {
809759
self.addr_cache.insert(authority, addresses);
810760
}

0 commit comments

Comments
 (0)