Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit 288ead0

Browse files
authored
client/authority-discovery: Don't add own address to priority group (#6370)
* client/authority-discovery: Don't add own address to priority group In the scenario of a validator publishing the address of its sentry node to the DHT, said sentry node should not add its own Multiaddr to the peerset "authority" priority group. Related to 70cfeff. * client/authority-discovery: Remove unused import PeerId * client/authority-discovery/tests: Add tcp protocol to multiaddresses
1 parent 24cbfc4 commit 288ead0

File tree

2 files changed

+122
-8
lines changed

2 files changed

+122
-8
lines changed

client/authority-discovery/src/lib.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,19 +58,26 @@ use futures::task::{Context, Poll};
5858
use futures::{Future, FutureExt, ready, Stream, StreamExt};
5959
use futures_timer::Delay;
6060

61+
use addr_cache::AddrCache;
6162
use codec::Decode;
6263
use error::{Error, Result};
64+
use libp2p::core::multiaddr;
6365
use log::{debug, error, log_enabled};
6466
use prometheus_endpoint::{Counter, CounterVec, Gauge, Opts, U64, register};
6567
use prost::Message;
6668
use sc_client_api::blockchain::HeaderBackend;
67-
use sc_network::{Multiaddr, config::MultiaddrWithPeerId, DhtEvent, ExHashT, NetworkStateInfo};
69+
use sc_network::{
70+
config::MultiaddrWithPeerId,
71+
DhtEvent,
72+
ExHashT,
73+
Multiaddr,
74+
NetworkStateInfo,
75+
};
6876
use sp_authority_discovery::{AuthorityDiscoveryApi, AuthorityId, AuthoritySignature, AuthorityPair};
6977
use sp_core::crypto::{key_types, Pair};
7078
use sp_core::traits::BareCryptoStorePtr;
7179
use sp_runtime::{traits::Block as BlockT, generic::BlockId};
7280
use sp_api::ProvideRuntimeApi;
73-
use addr_cache::AddrCache;
7481

7582
#[cfg(test)]
7683
mod tests;
@@ -233,7 +240,7 @@ where
233240
.collect(),
234241
None => self.network.external_addresses()
235242
.into_iter()
236-
.map(|a| a.with(libp2p::core::multiaddr::Protocol::P2p(
243+
.map(|a| a.with(multiaddr::Protocol::P2p(
237244
self.network.local_peer_id().into(),
238245
)))
239246
.map(|a| a.to_vec())
@@ -423,6 +430,8 @@ where
423430
.get(&remote_key)
424431
.ok_or(Error::MatchingHashedAuthorityIdWithAuthorityId)?;
425432

433+
let local_peer_id = multiaddr::Protocol::P2p(self.network.local_peer_id().into());
434+
426435
let remote_addresses: Vec<Multiaddr> = values.into_iter()
427436
.map(|(_k, v)| {
428437
let schema::SignedAuthorityAddresses { signature, addresses } =
@@ -447,7 +456,13 @@ where
447456
Ok(addresses)
448457
})
449458
.collect::<Result<Vec<Vec<Multiaddr>>>>()?
450-
.into_iter().flatten().collect();
459+
.into_iter()
460+
.flatten()
461+
// Ignore own addresses.
462+
.filter(|addr| !addr.iter().any(|protocol|
463+
protocol == local_peer_id
464+
))
465+
.collect();
451466

452467
if !remote_addresses.is_empty() {
453468
self.addr_cache.insert(authority_id.clone(), remote_addresses);

client/authority-discovery/src/tests.rs

Lines changed: 103 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ use futures::future::{poll_fn, FutureExt};
2424
use futures::sink::SinkExt;
2525
use futures::task::LocalSpawn;
2626
use futures::poll;
27-
use libp2p::{kad, PeerId};
27+
use libp2p::{kad, core::multiaddr, PeerId};
2828

2929
use sp_api::{ProvideRuntimeApi, ApiRef};
30-
use sp_core::testing::KeyStore;
30+
use sp_core::{crypto::Public, testing::KeyStore};
3131
use sp_runtime::traits::{Zero, Block as BlockT, NumberFor};
3232
use substrate_test_runtime_client::runtime::Block;
3333

@@ -210,7 +210,7 @@ impl NetworkStateInfo for TestNetwork {
210210
}
211211

212212
fn external_addresses(&self) -> Vec<Multiaddr> {
213-
vec!["/ip6/2001:db8::".parse().unwrap()]
213+
vec!["/ip6/2001:db8::/tcp/30333".parse().unwrap()]
214214
}
215215
}
216216

@@ -281,7 +281,7 @@ fn publish_discover_cycle() {
281281
let peer_id = network.local_peer_id();
282282
let address = network.external_addresses().pop().unwrap();
283283

284-
address.with(libp2p::core::multiaddr::Protocol::P2p(
284+
address.with(multiaddr::Protocol::P2p(
285285
peer_id.into(),
286286
))
287287
};
@@ -461,3 +461,102 @@ fn dont_stop_polling_when_error_is_returned() {
461461
}
462462
);
463463
}
464+
465+
/// In the scenario of a validator publishing the address of its sentry node to
466+
/// the DHT, said sentry node should not add its own Multiaddr to the
467+
/// peerset "authority" priority group.
468+
#[test]
469+
fn never_add_own_address_to_priority_group() {
470+
let validator_key_store = KeyStore::new();
471+
let validator_public = validator_key_store
472+
.write()
473+
.sr25519_generate_new(key_types::AUTHORITY_DISCOVERY, None)
474+
.unwrap();
475+
476+
let sentry_network: Arc<TestNetwork> = Arc::new(Default::default());
477+
478+
let sentry_multiaddr = {
479+
let peer_id = sentry_network.local_peer_id();
480+
let address: Multiaddr = "/ip6/2001:db8:0:0:0:0:0:2/tcp/30333".parse().unwrap();
481+
482+
address.with(multiaddr::Protocol::P2p(
483+
peer_id.into(),
484+
))
485+
};
486+
487+
// Address of some other sentry node of `validator`.
488+
let random_multiaddr = {
489+
let peer_id = PeerId::random();
490+
let address: Multiaddr = "/ip6/2001:db8:0:0:0:0:0:1/tcp/30333".parse().unwrap();
491+
492+
address.with(multiaddr::Protocol::P2p(
493+
peer_id.into(),
494+
))
495+
};
496+
497+
let dht_event = {
498+
let addresses = vec![
499+
sentry_multiaddr.to_vec(),
500+
random_multiaddr.to_vec(),
501+
];
502+
503+
let mut serialized_addresses = vec![];
504+
schema::AuthorityAddresses { addresses }
505+
.encode(&mut serialized_addresses)
506+
.map_err(Error::EncodingProto)
507+
.unwrap();
508+
509+
let signature = validator_key_store.read()
510+
.sign_with(
511+
key_types::AUTHORITY_DISCOVERY,
512+
&validator_public.clone().into(),
513+
serialized_addresses.as_slice(),
514+
)
515+
.map_err(|_| Error::Signing)
516+
.unwrap();
517+
518+
let mut signed_addresses = vec![];
519+
schema::SignedAuthorityAddresses {
520+
addresses: serialized_addresses.clone(),
521+
signature,
522+
}
523+
.encode(&mut signed_addresses)
524+
.map_err(Error::EncodingProto)
525+
.unwrap();
526+
527+
let key = hash_authority_id(&validator_public.to_raw_vec());
528+
let value = signed_addresses;
529+
(key, value)
530+
};
531+
532+
let (_dht_event_tx, dht_event_rx) = channel(1);
533+
let sentry_test_api = Arc::new(TestApi {
534+
// Make sure the sentry node identifies its validator as an authority.
535+
authorities: vec![validator_public.into()],
536+
});
537+
538+
let mut sentry_authority_discovery = AuthorityDiscovery::new(
539+
sentry_test_api,
540+
sentry_network.clone(),
541+
vec![],
542+
dht_event_rx.boxed(),
543+
Role::Sentry,
544+
None,
545+
);
546+
547+
sentry_authority_discovery.handle_dht_value_found_event(vec![dht_event]).unwrap();
548+
549+
assert_eq!(
550+
sentry_network.set_priority_group_call.lock().unwrap().len(), 1,
551+
"Expect authority discovery to set the priority set.",
552+
);
553+
554+
assert_eq!(
555+
sentry_network.set_priority_group_call.lock().unwrap()[0],
556+
(
557+
"authorities".to_string(),
558+
HashSet::from_iter(vec![random_multiaddr.clone()].into_iter(),)
559+
),
560+
"Expect authority discovery to only add `random_multiaddr`."
561+
);
562+
}

0 commit comments

Comments
 (0)