From 83052fe5732ae571c28a259a64d7576a5f1229ce Mon Sep 17 00:00:00 2001
From: Max Inden <mail@max-inden.de>
Date: Mon, 12 Aug 2019 19:23:59 +0200
Subject: [PATCH] core/network: Surface peerset's `set_priority_group` in
 NetworkService (#3376)

`PeerSetHandle.set_priority_group` allows modifying a priority group by
group identifier. With this commit the function can be accessed through
`NetworkService`.

This is need in order for a validator to connect to as many other
validators as configured without reserving a specific connection slot
for them.
---
 substrate/core/network/src/config.rs  |  9 +++++++--
 substrate/core/network/src/service.rs | 22 ++++++++++++++++++++--
 2 files changed, 27 insertions(+), 4 deletions(-)

diff --git a/substrate/core/network/src/config.rs b/substrate/core/network/src/config.rs
index 6cabb1217b0..46bb8aeff4d 100644
--- a/substrate/core/network/src/config.rs
+++ b/substrate/core/network/src/config.rs
@@ -163,7 +163,8 @@ impl ProtocolId {
 	}
 }
 
-/// Parses a string address and returns the component, if valid.
+/// Parses a string address and splits it into Multiaddress and PeerId, if
+/// valid.
 ///
 /// # Example
 ///
@@ -177,8 +178,12 @@ impl ProtocolId {
 /// ```
 ///
 pub fn parse_str_addr(addr_str: &str) -> Result<(PeerId, Multiaddr), ParseErr> {
-	let mut addr: Multiaddr = addr_str.parse()?;
+	let addr: Multiaddr = addr_str.parse()?;
+	parse_addr(addr)
+}
 
+/// Splits a Multiaddress into a Multiaddress and PeerId.
+pub fn parse_addr(mut addr: Multiaddr)-> Result<(PeerId, Multiaddr), ParseErr> {
 	let who = match addr.pop() {
 		Some(multiaddr::Protocol::P2p(key)) => PeerId::from_multihash(key)
 			.map_err(|_| ParseErr::InvalidPeerId)?,
diff --git a/substrate/core/network/src/service.rs b/substrate/core/network/src/service.rs
index eed5de85eda..d5ba8db7ae4 100644
--- a/substrate/core/network/src/service.rs
+++ b/substrate/core/network/src/service.rs
@@ -25,7 +25,7 @@
 //! The methods of the [`NetworkService`] are implemented by sending a message over a channel,
 //! which is then processed by [`NetworkWorker::poll`].
 
-use std::{collections::HashMap, fs, marker::PhantomData, io, path::Path};
+use std::{collections::{HashMap, HashSet}, fs, marker::PhantomData, io, path::Path};
 use std::sync::{Arc, atomic::{AtomicBool, AtomicUsize, Ordering}};
 
 use consensus::import_queue::{ImportQueue, Link};
@@ -40,7 +40,7 @@ use parking_lot::Mutex;
 use peerset::PeersetHandle;
 use sr_primitives::{traits::{Block as BlockT, NumberFor}, ConsensusEngineId};
 
-use crate::{behaviour::{Behaviour, BehaviourOut}, config::parse_str_addr};
+use crate::{behaviour::{Behaviour, BehaviourOut}, config::{parse_str_addr, parse_addr}};
 use crate::{NetworkState, NetworkStateNotConnectedPeer, NetworkStatePeer};
 use crate::{transport, config::NodeKeyConfig, config::NonReservedPeerMode};
 use crate::config::{Params, TransportConfig};
@@ -497,6 +497,24 @@ impl<B: BlockT + 'static, S: NetworkSpecialization<B>, H: ExHashT> NetworkServic
 		Ok(())
 	}
 
+	/// Modify a peerset priority group.
+	pub fn set_priority_group(&self, group_id: String, peers: HashSet<Multiaddr>) -> Result<(), String> {
+		let peers = peers.into_iter().map(|p| {
+			parse_addr(p).map_err(|e| format!("{:?}", e))
+		}).collect::<Result<Vec<(PeerId, Multiaddr)>, String>>()?;
+
+		let peer_ids = peers.iter().map(|(peer_id, _addr)| peer_id.clone()).collect();
+		self.peerset.set_priority_group(group_id, peer_ids);
+
+		for (peer_id, addr) in peers.into_iter() {
+			let _ = self
+				.to_worker
+				.unbounded_send(ServerToWorkerMsg::AddKnownAddress(peer_id, addr));
+		}
+
+		Ok(())
+	}
+
 	/// Returns the number of peers we're connected to.
 	pub fn num_connected(&self) -> usize {
 		self.num_connected.load(Ordering::Relaxed)
-- 
GitLab