Network sync refactoring (part 6) (#11940)

* Extract `NetworkKVProvider` trait in `sc-authority-discovery` and remove unnecessary dependency

* Extract `NetworkSyncForkRequest` trait in `sc-finality-grandpa`

* Relax requirements on `SyncOracle` trait, remove extra native methods from `NetworkService` that are already provided by trait impls

* Move `NetworkSigner` trait from `sc-authority-discovery` into `sc-network-common` and de-duplicate methods on `NetworkService`

* Move `NetworkKVProvider` trait from `sc-authority-discovery` into `sc-network-common` and de-duplicate methods on `NetworkService`

* Minimize `sc-authority-discovery` dependency on `sc-network`

* Move `NetworkSyncForkRequest` trait from `sc-finality-grandpa` to `sc-network-common` and de-duplicate methods in `NetworkService`

* Extract `NetworkStatusProvider` trait and de-duplicate methods on `NetworkService`

* Extract `NetworkPeers` trait and de-duplicate methods on `NetworkService`

* Extract `NetworkEventStream` trait and de-duplicate methods on `NetworkService`

* Move more methods from `NetworkService` into `NetworkPeers` trait

* Move `NetworkStateInfo` trait into `sc-network-common`

* Extract `NetworkNotification` trait and de-duplicate methods on `NetworkService`

* Extract `NetworkRequest` trait and de-duplicate methods on `NetworkService`

* Remove `NetworkService::local_peer_id()`, it is already provided by `NetworkStateInfo` impl

* Extract `NetworkTransaction` trait and de-duplicate methods on `NetworkService`

* Extract `NetworkBlock` trait and de-duplicate methods on `NetworkService`

* Remove dependencies on `NetworkService` from most of the methods of `sc-service`

* Address simple review comments
This commit is contained in:
Nazar Mokrynskyi
2022-08-09 21:28:32 +03:00
committed by GitHub
parent 9c56e79c43
commit a685582bfd
49 changed files with 1889 additions and 1029 deletions
@@ -31,11 +31,10 @@
//! - Send events by calling [`OutChannels::send`]. Events are cloned for each sender in the
//! collection.
use crate::Event;
use futures::{channel::mpsc, prelude::*, ready, stream::FusedStream};
use parking_lot::Mutex;
use prometheus_endpoint::{register, CounterVec, GaugeVec, Opts, PrometheusError, Registry, U64};
use sc_network_common::protocol::event::Event;
use std::{
cell::RefCell,
fmt,
@@ -1,50 +0,0 @@
// This file is part of Substrate.
//
// Copyright (C) 2017-2022 Parity Technologies (UK) Ltd.
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//
// If you read this, you are very thorough, congratulations.
use super::*;
/// A result of signing a message with a network identity. Since `PeerId` is potentially a hash of a
/// `PublicKey`, you need to reveal the `PublicKey` next to the signature, so the verifier can check
/// if the signature was made by the entity that controls a given `PeerId`.
pub struct Signature {
/// The public key derived from the network identity that signed the message.
pub public_key: PublicKey,
/// The actual signature made for the message signed.
pub bytes: Vec<u8>,
}
impl Signature {
/// Create a signature for a message with a given network identity.
pub fn sign_message(
message: impl AsRef<[u8]>,
keypair: &Keypair,
) -> Result<Self, SigningError> {
let public_key = keypair.public();
let bytes = keypair.sign(message.as_ref())?;
Ok(Self { public_key, bytes })
}
/// Verify whether the signature was made for the given message by the entity that controls the
/// given `PeerId`.
pub fn verify(&self, message: impl AsRef<[u8]>, peer_id: &PeerId) -> bool {
*peer_id == self.public_key.to_peer_id() &&
self.public_key.verify(message.as_ref(), &self.bytes)
}
}
+30 -29
View File
@@ -16,11 +16,15 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use crate::{config, Event, NetworkService, NetworkWorker};
use crate::{config, NetworkService, NetworkWorker};
use futures::prelude::*;
use libp2p::PeerId;
use sc_network_common::config::ProtocolId;
use sc_network_common::{
config::ProtocolId,
protocol::event::Event,
service::{NetworkEventStream, NetworkNotification, NetworkPeers, NetworkStateInfo},
};
use sc_network_light::light_client_requests::handler::LightClientRequestHandler;
use sc_network_sync::{
block_request_handler::BlockRequestHandler, state_request_handler::StateRequestHandler,
@@ -192,7 +196,7 @@ fn build_nodes_one_proto() -> (
set_config: config::SetConfig {
reserved_nodes: vec![config::MultiaddrWithPeerId {
multiaddr: listen_addr,
peer_id: node1.local_peer_id().clone(),
peer_id: node1.local_peer_id(),
}],
..Default::default()
},
@@ -214,18 +218,10 @@ fn notifications_state_consistent() {
// Write some initial notifications that shouldn't get through.
for _ in 0..(rand::random::<u8>() % 5) {
node1.write_notification(
node2.local_peer_id().clone(),
PROTOCOL_NAME,
b"hello world".to_vec(),
);
node1.write_notification(node2.local_peer_id(), PROTOCOL_NAME, b"hello world".to_vec());
}
for _ in 0..(rand::random::<u8>() % 5) {
node2.write_notification(
node1.local_peer_id().clone(),
PROTOCOL_NAME,
b"hello world".to_vec(),
);
node2.write_notification(node1.local_peer_id(), PROTOCOL_NAME, b"hello world".to_vec());
}
async_std::task::block_on(async move {
@@ -249,14 +245,14 @@ fn notifications_state_consistent() {
// test consists in ensuring that notifications get ignored if the stream isn't open.
if rand::random::<u8>() % 5 >= 3 {
node1.write_notification(
node2.local_peer_id().clone(),
node2.local_peer_id(),
PROTOCOL_NAME,
b"hello world".to_vec(),
);
}
if rand::random::<u8>() % 5 >= 3 {
node2.write_notification(
node1.local_peer_id().clone(),
node1.local_peer_id(),
PROTOCOL_NAME,
b"hello world".to_vec(),
);
@@ -264,10 +260,10 @@ fn notifications_state_consistent() {
// Also randomly disconnect the two nodes from time to time.
if rand::random::<u8>() % 20 == 0 {
node1.disconnect_peer(node2.local_peer_id().clone(), PROTOCOL_NAME);
node1.disconnect_peer(node2.local_peer_id(), PROTOCOL_NAME);
}
if rand::random::<u8>() % 20 == 0 {
node2.disconnect_peer(node1.local_peer_id().clone(), PROTOCOL_NAME);
node2.disconnect_peer(node1.local_peer_id(), PROTOCOL_NAME);
}
// Grab next event from either `events_stream1` or `events_stream2`.
@@ -295,7 +291,7 @@ fn notifications_state_consistent() {
something_happened = true;
assert!(!node1_to_node2_open);
node1_to_node2_open = true;
assert_eq!(remote, *node2.local_peer_id());
assert_eq!(remote, node2.local_peer_id());
},
future::Either::Right(Event::NotificationStreamOpened {
remote, protocol, ..
@@ -304,7 +300,7 @@ fn notifications_state_consistent() {
something_happened = true;
assert!(!node2_to_node1_open);
node2_to_node1_open = true;
assert_eq!(remote, *node1.local_peer_id());
assert_eq!(remote, node1.local_peer_id());
},
future::Either::Left(Event::NotificationStreamClosed {
remote, protocol, ..
@@ -312,7 +308,7 @@ fn notifications_state_consistent() {
if protocol == PROTOCOL_NAME {
assert!(node1_to_node2_open);
node1_to_node2_open = false;
assert_eq!(remote, *node2.local_peer_id());
assert_eq!(remote, node2.local_peer_id());
},
future::Either::Right(Event::NotificationStreamClosed {
remote, protocol, ..
@@ -320,14 +316,14 @@ fn notifications_state_consistent() {
if protocol == PROTOCOL_NAME {
assert!(node2_to_node1_open);
node2_to_node1_open = false;
assert_eq!(remote, *node1.local_peer_id());
assert_eq!(remote, node1.local_peer_id());
},
future::Either::Left(Event::NotificationsReceived { remote, .. }) => {
assert!(node1_to_node2_open);
assert_eq!(remote, *node2.local_peer_id());
assert_eq!(remote, node2.local_peer_id());
if rand::random::<u8>() % 5 >= 4 {
node1.write_notification(
node2.local_peer_id().clone(),
node2.local_peer_id(),
PROTOCOL_NAME,
b"hello world".to_vec(),
);
@@ -335,10 +331,10 @@ fn notifications_state_consistent() {
},
future::Either::Right(Event::NotificationsReceived { remote, .. }) => {
assert!(node2_to_node1_open);
assert_eq!(remote, *node1.local_peer_id());
assert_eq!(remote, node1.local_peer_id());
if rand::random::<u8>() % 5 >= 4 {
node2.write_notification(
node1.local_peer_id().clone(),
node1.local_peer_id(),
PROTOCOL_NAME,
b"hello world".to_vec(),
);
@@ -373,7 +369,7 @@ fn lots_of_incoming_peers_works() {
..config::NetworkConfiguration::new_local()
});
let main_node_peer_id = *main_node.local_peer_id();
let main_node_peer_id = main_node.local_peer_id();
// We spawn background tasks and push them in this `Vec`. They will all be waited upon before
// this test ends.
@@ -476,8 +472,13 @@ fn notifications_back_pressure() {
// Sending!
for num in 0..TOTAL_NOTIFS {
let notif = node1.notification_sender(node2_id.clone(), PROTOCOL_NAME).unwrap();
notif.ready().await.unwrap().send(format!("hello #{}", num)).unwrap();
let notif = node1.notification_sender(node2_id, PROTOCOL_NAME).unwrap();
notif
.ready()
.await
.unwrap()
.send(format!("hello #{}", num).into_bytes())
.unwrap();
}
receiver.await;
@@ -514,7 +515,7 @@ fn fallback_name_working() {
set_config: config::SetConfig {
reserved_nodes: vec![config::MultiaddrWithPeerId {
multiaddr: listen_addr,
peer_id: node1.local_peer_id().clone(),
peer_id: node1.local_peer_id(),
}],
..Default::default()
},