mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-09 20:11:09 +00:00
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:
Generated
+9
-2
@@ -4686,6 +4686,7 @@ dependencies = [
|
||||
"sc-finality-grandpa",
|
||||
"sc-keystore",
|
||||
"sc-network",
|
||||
"sc-network-common",
|
||||
"sc-rpc",
|
||||
"sc-service",
|
||||
"sc-service-test",
|
||||
@@ -7702,7 +7703,6 @@ dependencies = [
|
||||
name = "sc-authority-discovery"
|
||||
version = "0.10.0-dev"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"futures",
|
||||
"futures-timer",
|
||||
"ip_network",
|
||||
@@ -7715,6 +7715,7 @@ dependencies = [
|
||||
"rand 0.7.3",
|
||||
"sc-client-api",
|
||||
"sc-network",
|
||||
"sc-network-common",
|
||||
"sp-api",
|
||||
"sp-authority-discovery",
|
||||
"sp-blockchain",
|
||||
@@ -8316,7 +8317,7 @@ dependencies = [
|
||||
"log",
|
||||
"parity-util-mem",
|
||||
"sc-client-api",
|
||||
"sc-network",
|
||||
"sc-network-common",
|
||||
"sc-transaction-pool-api",
|
||||
"sp-blockchain",
|
||||
"sp-runtime",
|
||||
@@ -8398,7 +8399,9 @@ dependencies = [
|
||||
name = "sc-network-common"
|
||||
version = "0.10.0-dev"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bitflags",
|
||||
"bytes",
|
||||
"futures",
|
||||
"libp2p",
|
||||
"parity-scale-codec",
|
||||
@@ -8409,6 +8412,7 @@ dependencies = [
|
||||
"sp-consensus",
|
||||
"sp-finality-grandpa",
|
||||
"sp-runtime",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -8424,6 +8428,7 @@ dependencies = [
|
||||
"lru",
|
||||
"quickcheck",
|
||||
"sc-network",
|
||||
"sc-network-common",
|
||||
"sp-runtime",
|
||||
"substrate-prometheus-endpoint",
|
||||
"substrate-test-runtime-client",
|
||||
@@ -8533,6 +8538,7 @@ dependencies = [
|
||||
"sc-client-api",
|
||||
"sc-client-db",
|
||||
"sc-network",
|
||||
"sc-network-common",
|
||||
"sc-transaction-pool",
|
||||
"sc-transaction-pool-api",
|
||||
"sc-utils",
|
||||
@@ -8741,6 +8747,7 @@ dependencies = [
|
||||
"sc-consensus",
|
||||
"sc-executor",
|
||||
"sc-network",
|
||||
"sc-network-common",
|
||||
"sc-service",
|
||||
"sc-transaction-pool-api",
|
||||
"sp-api",
|
||||
|
||||
@@ -66,6 +66,7 @@ sc-consensus = { version = "0.10.0-dev", path = "../../../client/consensus/commo
|
||||
sc-transaction-pool = { version = "4.0.0-dev", path = "../../../client/transaction-pool" }
|
||||
sc-transaction-pool-api = { version = "4.0.0-dev", path = "../../../client/transaction-pool/api" }
|
||||
sc-network = { version = "0.10.0-dev", path = "../../../client/network" }
|
||||
sc-network-common = { version = "0.10.0-dev", path = "../../../client/network/common" }
|
||||
sc-consensus-slots = { version = "0.10.0-dev", path = "../../../client/consensus/slots" }
|
||||
sc-consensus-babe = { version = "0.10.0-dev", path = "../../../client/consensus/babe" }
|
||||
sc-consensus-uncles = { version = "0.10.0-dev", path = "../../../client/consensus/uncles" }
|
||||
|
||||
@@ -29,7 +29,8 @@ use node_primitives::Block;
|
||||
use sc_client_api::{BlockBackend, ExecutorProvider};
|
||||
use sc_consensus_babe::{self, SlotProportion};
|
||||
use sc_executor::NativeElseWasmExecutor;
|
||||
use sc_network::{Event, NetworkService};
|
||||
use sc_network::NetworkService;
|
||||
use sc_network_common::{protocol::event::Event, service::NetworkEventStream};
|
||||
use sc_service::{config::Configuration, error::Error as ServiceError, RpcHandlers, TaskManager};
|
||||
use sc_telemetry::{Telemetry, TelemetryWorker};
|
||||
use sp_api::ProvideRuntimeApi;
|
||||
|
||||
@@ -17,7 +17,6 @@ targets = ["x86_64-unknown-linux-gnu"]
|
||||
prost-build = "0.10"
|
||||
|
||||
[dependencies]
|
||||
async-trait = "0.1"
|
||||
codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false }
|
||||
futures = "0.3.21"
|
||||
futures-timer = "3.0.1"
|
||||
@@ -29,6 +28,7 @@ rand = "0.7.2"
|
||||
thiserror = "1.0"
|
||||
prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.10.0-dev", path = "../../utils/prometheus" }
|
||||
sc-client-api = { version = "4.0.0-dev", path = "../api" }
|
||||
sc-network-common = { version = "0.10.0-dev", path = "../network/common" }
|
||||
sc-network = { version = "0.10.0-dev", path = "../network" }
|
||||
sp-api = { version = "4.0.0-dev", path = "../../primitives/api" }
|
||||
sp-authority-discovery = { version = "4.0.0-dev", path = "../../primitives/authority-discovery" }
|
||||
|
||||
@@ -39,8 +39,9 @@ use futures::{
|
||||
Stream,
|
||||
};
|
||||
|
||||
use libp2p::{Multiaddr, PeerId};
|
||||
use sc_client_api::blockchain::HeaderBackend;
|
||||
use sc_network::{DhtEvent, Multiaddr, PeerId};
|
||||
use sc_network_common::protocol::event::DhtEvent;
|
||||
use sp_api::ProvideRuntimeApi;
|
||||
use sp_authority_discovery::{AuthorityDiscoveryApi, AuthorityId};
|
||||
use sp_runtime::traits::Block as BlockT;
|
||||
|
||||
@@ -25,7 +25,7 @@ use futures::{
|
||||
SinkExt,
|
||||
};
|
||||
|
||||
use sc_network::{Multiaddr, PeerId};
|
||||
use libp2p::{Multiaddr, PeerId};
|
||||
use sp_authority_discovery::AuthorityId;
|
||||
|
||||
/// Service to interact with the [`crate::Worker`].
|
||||
|
||||
@@ -87,12 +87,12 @@ fn get_addresses_and_authority_id() {
|
||||
fn cryptos_are_compatible() {
|
||||
use sp_core::crypto::Pair;
|
||||
|
||||
let libp2p_secret = sc_network::Keypair::generate_ed25519();
|
||||
let libp2p_secret = libp2p::identity::Keypair::generate_ed25519();
|
||||
let libp2p_public = libp2p_secret.public();
|
||||
|
||||
let sp_core_secret = {
|
||||
let libp2p_ed_secret = match libp2p_secret.clone() {
|
||||
sc_network::Keypair::Ed25519(x) => x,
|
||||
libp2p::identity::Keypair::Ed25519(x) => x,
|
||||
_ => panic!("generate_ed25519 should have generated an Ed25519 key ¯\\_(ツ)_/¯"),
|
||||
};
|
||||
sp_core::ed25519::Pair::from_seed_slice(&libp2p_ed_secret.secret().as_ref()).unwrap()
|
||||
|
||||
@@ -32,19 +32,22 @@ use std::{
|
||||
use futures::{channel::mpsc, future, stream::Fuse, FutureExt, Stream, StreamExt};
|
||||
|
||||
use addr_cache::AddrCache;
|
||||
use async_trait::async_trait;
|
||||
use codec::Decode;
|
||||
use ip_network::IpNetwork;
|
||||
use libp2p::{
|
||||
core::multiaddr,
|
||||
multihash::{Multihash, MultihashDigest},
|
||||
Multiaddr, PeerId,
|
||||
};
|
||||
use log::{debug, error, log_enabled};
|
||||
use prometheus_endpoint::{register, Counter, CounterVec, Gauge, Opts, U64};
|
||||
use prost::Message;
|
||||
use rand::{seq::SliceRandom, thread_rng};
|
||||
use sc_client_api::blockchain::HeaderBackend;
|
||||
use sc_network::{DhtEvent, ExHashT, Multiaddr, NetworkStateInfo, PeerId};
|
||||
use sc_network_common::{
|
||||
protocol::event::DhtEvent,
|
||||
service::{KademliaKey, NetworkDHTProvider, NetworkSigner, NetworkStateInfo, Signature},
|
||||
};
|
||||
use sp_api::ProvideRuntimeApi;
|
||||
use sp_authority_discovery::{
|
||||
AuthorityDiscoveryApi, AuthorityId, AuthorityPair, AuthoritySignature,
|
||||
@@ -136,7 +139,7 @@ pub struct Worker<Client, Network, Block, DhtEventStream> {
|
||||
/// Queue of throttled lookups pending to be passed to the network.
|
||||
pending_lookups: Vec<AuthorityId>,
|
||||
/// Set of in-flight lookups.
|
||||
in_flight_lookups: HashMap<sc_network::KademliaKey, AuthorityId>,
|
||||
in_flight_lookups: HashMap<KademliaKey, AuthorityId>,
|
||||
|
||||
addr_cache: addr_cache::AddrCache,
|
||||
|
||||
@@ -464,10 +467,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_dht_value_found_event(
|
||||
&mut self,
|
||||
values: Vec<(sc_network::KademliaKey, Vec<u8>)>,
|
||||
) -> Result<()> {
|
||||
fn handle_dht_value_found_event(&mut self, values: Vec<(KademliaKey, Vec<u8>)>) -> Result<()> {
|
||||
// Ensure `values` is not empty and all its keys equal.
|
||||
let remote_key = single(values.iter().map(|(key, _)| key.clone()))
|
||||
.map_err(|_| Error::ReceivingDhtValueFoundEventWithDifferentKeys)?
|
||||
@@ -523,11 +523,11 @@ where
|
||||
// properly signed by the owner of the PeerId
|
||||
|
||||
if let Some(peer_signature) = peer_signature {
|
||||
let public_key =
|
||||
sc_network::PublicKey::from_protobuf_encoding(&peer_signature.public_key)
|
||||
.map_err(Error::ParsingLibp2pIdentity)?;
|
||||
let signature =
|
||||
sc_network::Signature { public_key, bytes: peer_signature.signature };
|
||||
let public_key = libp2p::identity::PublicKey::from_protobuf_encoding(
|
||||
&peer_signature.public_key,
|
||||
)
|
||||
.map_err(Error::ParsingLibp2pIdentity)?;
|
||||
let signature = Signature { public_key, bytes: peer_signature.signature };
|
||||
|
||||
if !signature.verify(record, &remote_peer_id) {
|
||||
return Err(Error::VerifyingDhtPayload)
|
||||
@@ -590,55 +590,15 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub trait NetworkSigner {
|
||||
/// Sign a message in the name of `self.local_peer_id()`
|
||||
fn sign_with_local_identity(
|
||||
&self,
|
||||
msg: impl AsRef<[u8]>,
|
||||
) -> std::result::Result<sc_network::Signature, sc_network::SigningError>;
|
||||
}
|
||||
|
||||
/// NetworkProvider provides [`Worker`] with all necessary hooks into the
|
||||
/// underlying Substrate networking. Using this trait abstraction instead of
|
||||
/// [`sc_network::NetworkService`] directly is necessary to unit test [`Worker`].
|
||||
#[async_trait]
|
||||
pub trait NetworkProvider: NetworkStateInfo + NetworkSigner {
|
||||
/// Start putting a value in the Dht.
|
||||
fn put_value(&self, key: sc_network::KademliaKey, value: Vec<u8>);
|
||||
/// `sc_network::NetworkService` directly is necessary to unit test [`Worker`].
|
||||
pub trait NetworkProvider: NetworkDHTProvider + NetworkStateInfo + NetworkSigner {}
|
||||
|
||||
/// Start getting a value from the Dht.
|
||||
fn get_value(&self, key: &sc_network::KademliaKey);
|
||||
}
|
||||
impl<T> NetworkProvider for T where T: NetworkDHTProvider + NetworkStateInfo + NetworkSigner {}
|
||||
|
||||
impl<B, H> NetworkSigner for sc_network::NetworkService<B, H>
|
||||
where
|
||||
B: BlockT + 'static,
|
||||
H: ExHashT,
|
||||
{
|
||||
fn sign_with_local_identity(
|
||||
&self,
|
||||
msg: impl AsRef<[u8]>,
|
||||
) -> std::result::Result<sc_network::Signature, sc_network::SigningError> {
|
||||
self.sign_with_local_identity(msg)
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl<B, H> NetworkProvider for sc_network::NetworkService<B, H>
|
||||
where
|
||||
B: BlockT + 'static,
|
||||
H: ExHashT,
|
||||
{
|
||||
fn put_value(&self, key: sc_network::KademliaKey, value: Vec<u8>) {
|
||||
self.put_value(key, value)
|
||||
}
|
||||
fn get_value(&self, key: &sc_network::KademliaKey) {
|
||||
self.get_value(key)
|
||||
}
|
||||
}
|
||||
|
||||
fn hash_authority_id(id: &[u8]) -> sc_network::KademliaKey {
|
||||
sc_network::KademliaKey::new(&libp2p::multihash::Code::Sha2_256.digest(id).digest())
|
||||
fn hash_authority_id(id: &[u8]) -> KademliaKey {
|
||||
KademliaKey::new(&libp2p::multihash::Code::Sha2_256.digest(id).digest())
|
||||
}
|
||||
|
||||
// Makes sure all values are the same and returns it
|
||||
@@ -685,7 +645,7 @@ async fn sign_record_with_authority_ids(
|
||||
peer_signature: Option<schema::PeerSignature>,
|
||||
key_store: &dyn CryptoStore,
|
||||
keys: Vec<CryptoTypePublicPair>,
|
||||
) -> Result<Vec<(sc_network::KademliaKey, Vec<u8>)>> {
|
||||
) -> Result<Vec<(KademliaKey, Vec<u8>)>> {
|
||||
let signatures = key_store
|
||||
.sign_with_all(key_types::AUTHORITY_DISCOVERY, keys.clone(), &serialized_record)
|
||||
.await
|
||||
|
||||
@@ -16,9 +16,10 @@
|
||||
// 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 libp2p::core::multiaddr::{Multiaddr, Protocol};
|
||||
|
||||
use sc_network::PeerId;
|
||||
use libp2p::{
|
||||
core::multiaddr::{Multiaddr, Protocol},
|
||||
PeerId,
|
||||
};
|
||||
use sp_authority_discovery::AuthorityId;
|
||||
use std::collections::{hash_map::Entry, HashMap, HashSet};
|
||||
|
||||
|
||||
@@ -21,9 +21,8 @@ mod schema_v1 {
|
||||
}
|
||||
|
||||
use super::*;
|
||||
use libp2p::multiaddr::Multiaddr;
|
||||
use libp2p::{multiaddr::Multiaddr, PeerId};
|
||||
use prost::Message;
|
||||
use sc_network::PeerId;
|
||||
|
||||
#[test]
|
||||
fn v2_decodes_v1() {
|
||||
@@ -56,7 +55,7 @@ fn v2_decodes_v1() {
|
||||
|
||||
#[test]
|
||||
fn v1_decodes_v2() {
|
||||
let peer_secret = sc_network::Keypair::generate_ed25519();
|
||||
let peer_secret = libp2p::identity::Keypair::generate_ed25519();
|
||||
let peer_public = peer_secret.public();
|
||||
let peer_id = peer_public.to_peer_id();
|
||||
let multiaddress: Multiaddr =
|
||||
|
||||
@@ -22,7 +22,6 @@ use std::{
|
||||
task::Poll,
|
||||
};
|
||||
|
||||
use async_trait::async_trait;
|
||||
use futures::{
|
||||
channel::mpsc::{self, channel},
|
||||
executor::{block_on, LocalPool},
|
||||
@@ -30,9 +29,10 @@ use futures::{
|
||||
sink::SinkExt,
|
||||
task::LocalSpawn,
|
||||
};
|
||||
use libp2p::{core::multiaddr, PeerId};
|
||||
use libp2p::{core::multiaddr, identity::Keypair, PeerId};
|
||||
use prometheus_endpoint::prometheus::default_registry;
|
||||
|
||||
use sc_network_common::service::{KademliaKey, Signature, SigningError};
|
||||
use sp_api::{ApiRef, ProvideRuntimeApi};
|
||||
use sp_keystore::{testing::KeyStore, CryptoStore};
|
||||
use sp_runtime::traits::{Block as BlockT, NumberFor, Zero};
|
||||
@@ -111,18 +111,18 @@ sp_api::mock_impl_runtime_apis! {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum TestNetworkEvent {
|
||||
GetCalled(sc_network::KademliaKey),
|
||||
PutCalled(sc_network::KademliaKey, Vec<u8>),
|
||||
GetCalled(KademliaKey),
|
||||
PutCalled(KademliaKey, Vec<u8>),
|
||||
}
|
||||
|
||||
pub struct TestNetwork {
|
||||
peer_id: PeerId,
|
||||
identity: sc_network::Keypair,
|
||||
identity: Keypair,
|
||||
external_addresses: Vec<Multiaddr>,
|
||||
// Whenever functions on `TestNetwork` are called, the function arguments are added to the
|
||||
// vectors below.
|
||||
pub put_value_call: Arc<Mutex<Vec<(sc_network::KademliaKey, Vec<u8>)>>>,
|
||||
pub get_value_call: Arc<Mutex<Vec<sc_network::KademliaKey>>>,
|
||||
pub put_value_call: Arc<Mutex<Vec<(KademliaKey, Vec<u8>)>>>,
|
||||
pub get_value_call: Arc<Mutex<Vec<KademliaKey>>>,
|
||||
event_sender: mpsc::UnboundedSender<TestNetworkEvent>,
|
||||
event_receiver: Option<mpsc::UnboundedReceiver<TestNetworkEvent>>,
|
||||
}
|
||||
@@ -136,7 +136,7 @@ impl TestNetwork {
|
||||
impl Default for TestNetwork {
|
||||
fn default() -> Self {
|
||||
let (tx, rx) = mpsc::unbounded();
|
||||
let identity = sc_network::Keypair::generate_ed25519();
|
||||
let identity = Keypair::generate_ed25519();
|
||||
TestNetwork {
|
||||
peer_id: identity.public().to_peer_id(),
|
||||
identity,
|
||||
@@ -153,21 +153,20 @@ impl NetworkSigner for TestNetwork {
|
||||
fn sign_with_local_identity(
|
||||
&self,
|
||||
msg: impl AsRef<[u8]>,
|
||||
) -> std::result::Result<sc_network::Signature, sc_network::SigningError> {
|
||||
sc_network::Signature::sign_message(msg, &self.identity)
|
||||
) -> std::result::Result<Signature, SigningError> {
|
||||
Signature::sign_message(msg, &self.identity)
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl NetworkProvider for TestNetwork {
|
||||
fn put_value(&self, key: sc_network::KademliaKey, value: Vec<u8>) {
|
||||
impl NetworkDHTProvider for TestNetwork {
|
||||
fn put_value(&self, key: KademliaKey, value: Vec<u8>) {
|
||||
self.put_value_call.lock().unwrap().push((key.clone(), value.clone()));
|
||||
self.event_sender
|
||||
.clone()
|
||||
.unbounded_send(TestNetworkEvent::PutCalled(key, value))
|
||||
.unwrap();
|
||||
}
|
||||
fn get_value(&self, key: &sc_network::KademliaKey) {
|
||||
fn get_value(&self, key: &KademliaKey) {
|
||||
self.get_value_call.lock().unwrap().push(key.clone());
|
||||
self.event_sender
|
||||
.clone()
|
||||
@@ -186,12 +185,16 @@ impl NetworkStateInfo for TestNetwork {
|
||||
}
|
||||
}
|
||||
|
||||
impl NetworkSigner for sc_network::Keypair {
|
||||
struct TestSigner<'a> {
|
||||
keypair: &'a Keypair,
|
||||
}
|
||||
|
||||
impl<'a> NetworkSigner for TestSigner<'a> {
|
||||
fn sign_with_local_identity(
|
||||
&self,
|
||||
msg: impl AsRef<[u8]>,
|
||||
) -> std::result::Result<sc_network::Signature, sc_network::SigningError> {
|
||||
sc_network::Signature::sign_message(msg, self)
|
||||
) -> std::result::Result<Signature, SigningError> {
|
||||
Signature::sign_message(msg, self.keypair)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,7 +203,7 @@ async fn build_dht_event<Signer: NetworkSigner>(
|
||||
public_key: AuthorityId,
|
||||
key_store: &dyn CryptoStore,
|
||||
network: Option<&Signer>,
|
||||
) -> Vec<(sc_network::KademliaKey, Vec<u8>)> {
|
||||
) -> Vec<(KademliaKey, Vec<u8>)> {
|
||||
let serialized_record =
|
||||
serialize_authority_record(serialize_addresses(addresses.into_iter())).unwrap();
|
||||
|
||||
@@ -313,7 +316,7 @@ fn publish_discover_cycle() {
|
||||
|
||||
let dht_event = {
|
||||
let (key, value) = network.put_value_call.lock().unwrap().pop().unwrap();
|
||||
sc_network::DhtEvent::ValueFound(vec![(key, value)])
|
||||
DhtEvent::ValueFound(vec![(key, value)])
|
||||
};
|
||||
|
||||
// Node B discovering node A's address.
|
||||
@@ -469,7 +472,7 @@ fn dont_stop_polling_dht_event_stream_after_bogus_event() {
|
||||
None,
|
||||
)
|
||||
.await;
|
||||
sc_network::DhtEvent::ValueFound(kv_pairs)
|
||||
DhtEvent::ValueFound(kv_pairs)
|
||||
};
|
||||
dht_event_tx.send(dht_event).await.expect("Channel has capacity of 1.");
|
||||
|
||||
@@ -487,7 +490,7 @@ fn dont_stop_polling_dht_event_stream_after_bogus_event() {
|
||||
struct DhtValueFoundTester {
|
||||
pub remote_key_store: KeyStore,
|
||||
pub remote_authority_public: sp_core::sr25519::Public,
|
||||
pub remote_node_key: sc_network::Keypair,
|
||||
pub remote_node_key: Keypair,
|
||||
pub local_worker: Option<
|
||||
Worker<
|
||||
TestApi,
|
||||
@@ -496,7 +499,7 @@ struct DhtValueFoundTester {
|
||||
sp_runtime::generic::Header<u64, sp_runtime::traits::BlakeTwo256>,
|
||||
substrate_test_runtime_client::runtime::Extrinsic,
|
||||
>,
|
||||
std::pin::Pin<Box<futures::channel::mpsc::Receiver<sc_network::DhtEvent>>>,
|
||||
std::pin::Pin<Box<futures::channel::mpsc::Receiver<DhtEvent>>>,
|
||||
>,
|
||||
>,
|
||||
}
|
||||
@@ -508,7 +511,7 @@ impl DhtValueFoundTester {
|
||||
block_on(remote_key_store.sr25519_generate_new(key_types::AUTHORITY_DISCOVERY, None))
|
||||
.unwrap();
|
||||
|
||||
let remote_node_key = sc_network::Keypair::generate_ed25519();
|
||||
let remote_node_key = Keypair::generate_ed25519();
|
||||
Self { remote_key_store, remote_authority_public, remote_node_key, local_worker: None }
|
||||
}
|
||||
|
||||
@@ -523,7 +526,7 @@ impl DhtValueFoundTester {
|
||||
fn process_value_found(
|
||||
&mut self,
|
||||
strict_record_validation: bool,
|
||||
values: Vec<(sc_network::KademliaKey, Vec<u8>)>,
|
||||
values: Vec<(KademliaKey, Vec<u8>)>,
|
||||
) -> Option<&HashSet<Multiaddr>> {
|
||||
let (_dht_event_tx, dht_event_rx) = channel(1);
|
||||
let local_test_api =
|
||||
@@ -583,7 +586,7 @@ fn strict_accept_address_with_peer_signature() {
|
||||
vec![addr.clone()],
|
||||
tester.remote_authority_public.clone().into(),
|
||||
&tester.remote_key_store,
|
||||
Some(&tester.remote_node_key),
|
||||
Some(&TestSigner { keypair: &tester.remote_node_key }),
|
||||
));
|
||||
|
||||
let cached_remote_addresses = tester.process_value_found(true, kv_pairs);
|
||||
@@ -598,12 +601,12 @@ fn strict_accept_address_with_peer_signature() {
|
||||
#[test]
|
||||
fn reject_address_with_rogue_peer_signature() {
|
||||
let mut tester = DhtValueFoundTester::new();
|
||||
let rogue_remote_node_key = sc_network::Keypair::generate_ed25519();
|
||||
let rogue_remote_node_key = Keypair::generate_ed25519();
|
||||
let kv_pairs = block_on(build_dht_event(
|
||||
vec![tester.multiaddr_with_peer_id(1)],
|
||||
tester.remote_authority_public.clone().into(),
|
||||
&tester.remote_key_store,
|
||||
Some(&rogue_remote_node_key),
|
||||
Some(&TestSigner { keypair: &rogue_remote_node_key }),
|
||||
));
|
||||
|
||||
let cached_remote_addresses = tester.process_value_found(false, kv_pairs);
|
||||
@@ -621,7 +624,7 @@ fn reject_address_with_invalid_peer_signature() {
|
||||
vec![tester.multiaddr_with_peer_id(1)],
|
||||
tester.remote_authority_public.clone().into(),
|
||||
&tester.remote_key_store,
|
||||
Some(&tester.remote_node_key),
|
||||
Some(&TestSigner { keypair: &tester.remote_node_key }),
|
||||
));
|
||||
// tamper with the signature
|
||||
let mut record = schema::SignedAuthorityRecord::decode(kv_pairs[0].1.as_slice()).unwrap();
|
||||
@@ -808,7 +811,7 @@ fn lookup_throttling() {
|
||||
None,
|
||||
)
|
||||
.await;
|
||||
sc_network::DhtEvent::ValueFound(kv_pairs)
|
||||
DhtEvent::ValueFound(kv_pairs)
|
||||
};
|
||||
dht_event_tx.send(dht_event).await.expect("Channel has capacity of 1.");
|
||||
|
||||
@@ -822,7 +825,7 @@ fn lookup_throttling() {
|
||||
|
||||
// Make second one fail.
|
||||
let remote_hash = network.get_value_call.lock().unwrap().pop().unwrap();
|
||||
let dht_event = sc_network::DhtEvent::ValueNotFound(remote_hash);
|
||||
let dht_event = DhtEvent::ValueNotFound(remote_hash);
|
||||
dht_event_tx.send(dht_event).await.expect("Channel has capacity of 1.");
|
||||
|
||||
// Assert worker to trigger another lookup.
|
||||
|
||||
@@ -518,7 +518,7 @@ pub fn start_mining_worker<Block, C, S, Algorithm, E, SO, L, CIDP, CAW>(
|
||||
select_chain: S,
|
||||
algorithm: Algorithm,
|
||||
mut env: E,
|
||||
mut sync_oracle: SO,
|
||||
sync_oracle: SO,
|
||||
justification_sync_link: L,
|
||||
pre_runtime: Option<Vec<u8>>,
|
||||
create_inherent_data_providers: CIDP,
|
||||
|
||||
@@ -490,7 +490,7 @@ pub async fn start_slot_worker<B, C, W, SO, CIDP, CAW, Proof>(
|
||||
slot_duration: SlotDuration,
|
||||
client: C,
|
||||
mut worker: W,
|
||||
mut sync_oracle: SO,
|
||||
sync_oracle: SO,
|
||||
create_inherent_data_providers: CIDP,
|
||||
can_author_with: CAW,
|
||||
) where
|
||||
|
||||
@@ -89,7 +89,8 @@ use log::{debug, trace};
|
||||
use parity_scale_codec::{Decode, Encode};
|
||||
use prometheus_endpoint::{register, CounterVec, Opts, PrometheusError, Registry, U64};
|
||||
use rand::seq::SliceRandom;
|
||||
use sc_network::{ObservedRole, PeerId, ReputationChange};
|
||||
use sc_network::{PeerId, ReputationChange};
|
||||
use sc_network_common::protocol::event::ObservedRole;
|
||||
use sc_network_gossip::{MessageIntent, ValidatorContext};
|
||||
use sc_telemetry::{telemetry, TelemetryHandle, CONSENSUS_DEBUG};
|
||||
use sc_utils::mpsc::{tracing_unbounded, TracingUnboundedReceiver, TracingUnboundedSender};
|
||||
|
||||
@@ -45,7 +45,7 @@ use finality_grandpa::{
|
||||
Message::{Precommit, Prevote, PrimaryPropose},
|
||||
};
|
||||
use parity_scale_codec::{Decode, Encode};
|
||||
use sc_network::{NetworkService, ReputationChange};
|
||||
use sc_network::ReputationChange;
|
||||
use sc_network_gossip::{GossipEngine, Network as GossipNetwork};
|
||||
use sc_telemetry::{telemetry, TelemetryHandle, CONSENSUS_DEBUG, CONSENSUS_INFO};
|
||||
use sp_keystore::SyncCryptoStorePtr;
|
||||
@@ -58,6 +58,7 @@ use crate::{
|
||||
use gossip::{
|
||||
FullCatchUpMessage, FullCommitMessage, GossipMessage, GossipValidator, PeerReport, VoteMessage,
|
||||
};
|
||||
use sc_network_common::service::{NetworkBlock, NetworkSyncForkRequest};
|
||||
use sc_utils::mpsc::TracingUnboundedReceiver;
|
||||
use sp_finality_grandpa::{AuthorityId, AuthoritySignature, RoundNumber, SetId as SetIdNumber};
|
||||
|
||||
@@ -156,34 +157,26 @@ const TELEMETRY_VOTERS_LIMIT: usize = 10;
|
||||
///
|
||||
/// Something that provides both the capabilities needed for the `gossip_network::Network` trait as
|
||||
/// well as the ability to set a fork sync request for a particular block.
|
||||
pub trait Network<Block: BlockT>: GossipNetwork<Block> + Clone + Send + 'static {
|
||||
/// Notifies the sync service to try and sync the given block from the given
|
||||
/// peers.
|
||||
///
|
||||
/// If the given vector of peers is empty then the underlying implementation
|
||||
/// should make a best effort to fetch the block from any peers it is
|
||||
/// connected to (NOTE: this assumption will change in the future #3629).
|
||||
fn set_sync_fork_request(
|
||||
&self,
|
||||
peers: Vec<sc_network::PeerId>,
|
||||
hash: Block::Hash,
|
||||
number: NumberFor<Block>,
|
||||
);
|
||||
pub trait Network<Block: BlockT>:
|
||||
NetworkSyncForkRequest<Block::Hash, NumberFor<Block>>
|
||||
+ NetworkBlock<Block::Hash, NumberFor<Block>>
|
||||
+ GossipNetwork<Block>
|
||||
+ Clone
|
||||
+ Send
|
||||
+ 'static
|
||||
{
|
||||
}
|
||||
|
||||
impl<B, H> Network<B> for Arc<NetworkService<B, H>>
|
||||
impl<Block, T> Network<Block> for T
|
||||
where
|
||||
B: BlockT,
|
||||
H: sc_network::ExHashT,
|
||||
Block: BlockT,
|
||||
T: NetworkSyncForkRequest<Block::Hash, NumberFor<Block>>
|
||||
+ NetworkBlock<Block::Hash, NumberFor<Block>>
|
||||
+ GossipNetwork<Block>
|
||||
+ Clone
|
||||
+ Send
|
||||
+ 'static,
|
||||
{
|
||||
fn set_sync_fork_request(
|
||||
&self,
|
||||
peers: Vec<sc_network::PeerId>,
|
||||
hash: B::Hash,
|
||||
number: NumberFor<B>,
|
||||
) {
|
||||
NetworkService::set_sync_fork_request(self, peers, hash, number)
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a unique topic for a round and set-id combo.
|
||||
@@ -467,7 +460,7 @@ impl<B: BlockT, N: Network<B>> NetworkBridge<B, N> {
|
||||
hash: B::Hash,
|
||||
number: NumberFor<B>,
|
||||
) {
|
||||
Network::set_sync_fork_request(&self.service, peers, hash, number)
|
||||
self.service.set_sync_fork_request(peers, hash, number)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,14 @@ use super::{
|
||||
use crate::{communication::grandpa_protocol_name, environment::SharedVoterSetState};
|
||||
use futures::prelude::*;
|
||||
use parity_scale_codec::Encode;
|
||||
use sc_network::{config::Role, Event as NetworkEvent, ObservedRole, PeerId};
|
||||
use sc_network::{config::Role, Multiaddr, PeerId, ReputationChange};
|
||||
use sc_network_common::{
|
||||
protocol::event::{Event as NetworkEvent, ObservedRole},
|
||||
service::{
|
||||
NetworkBlock, NetworkEventStream, NetworkNotification, NetworkPeers,
|
||||
NetworkSyncForkRequest, NotificationSender, NotificationSenderError,
|
||||
},
|
||||
};
|
||||
use sc_network_gossip::Validator;
|
||||
use sc_network_test::{Block, Hash};
|
||||
use sc_utils::mpsc::{tracing_unbounded, TracingUnboundedReceiver, TracingUnboundedSender};
|
||||
@@ -34,6 +41,7 @@ use sp_keyring::Ed25519Keyring;
|
||||
use sp_runtime::traits::NumberFor;
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
collections::HashSet,
|
||||
pin::Pin,
|
||||
sync::Arc,
|
||||
task::{Context, Poll},
|
||||
@@ -42,8 +50,8 @@ use std::{
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum Event {
|
||||
EventStream(TracingUnboundedSender<NetworkEvent>),
|
||||
WriteNotification(sc_network::PeerId, Vec<u8>),
|
||||
Report(sc_network::PeerId, sc_network::ReputationChange),
|
||||
WriteNotification(PeerId, Vec<u8>),
|
||||
Report(PeerId, ReputationChange),
|
||||
Announce(Hash),
|
||||
}
|
||||
|
||||
@@ -52,40 +60,113 @@ pub(crate) struct TestNetwork {
|
||||
sender: TracingUnboundedSender<Event>,
|
||||
}
|
||||
|
||||
impl sc_network_gossip::Network<Block> for TestNetwork {
|
||||
fn event_stream(&self) -> Pin<Box<dyn Stream<Item = NetworkEvent> + Send>> {
|
||||
impl NetworkPeers for TestNetwork {
|
||||
fn set_authorized_peers(&self, _peers: HashSet<PeerId>) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn set_authorized_only(&self, _reserved_only: bool) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn add_known_address(&self, _peer_id: PeerId, _addr: Multiaddr) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn report_peer(&self, who: PeerId, cost_benefit: ReputationChange) {
|
||||
let _ = self.sender.unbounded_send(Event::Report(who, cost_benefit));
|
||||
}
|
||||
|
||||
fn disconnect_peer(&self, _who: PeerId, _protocol: Cow<'static, str>) {}
|
||||
|
||||
fn accept_unreserved_peers(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn deny_unreserved_peers(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn add_reserved_peer(&self, _peer: String) -> Result<(), String> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn remove_reserved_peer(&self, _peer_id: PeerId) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn set_reserved_peers(
|
||||
&self,
|
||||
_protocol: Cow<'static, str>,
|
||||
_peers: HashSet<Multiaddr>,
|
||||
) -> Result<(), String> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn add_peers_to_reserved_set(
|
||||
&self,
|
||||
_protocol: Cow<'static, str>,
|
||||
_peers: HashSet<Multiaddr>,
|
||||
) -> Result<(), String> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn remove_peers_from_reserved_set(&self, _protocol: Cow<'static, str>, _peers: Vec<PeerId>) {}
|
||||
|
||||
fn add_to_peers_set(
|
||||
&self,
|
||||
_protocol: Cow<'static, str>,
|
||||
_peers: HashSet<Multiaddr>,
|
||||
) -> Result<(), String> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn remove_from_peers_set(&self, _protocol: Cow<'static, str>, _peers: Vec<PeerId>) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn sync_num_connected(&self) -> usize {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
impl NetworkEventStream for TestNetwork {
|
||||
fn event_stream(
|
||||
&self,
|
||||
_name: &'static str,
|
||||
) -> Pin<Box<dyn Stream<Item = NetworkEvent> + Send>> {
|
||||
let (tx, rx) = tracing_unbounded("test");
|
||||
let _ = self.sender.unbounded_send(Event::EventStream(tx));
|
||||
Box::pin(rx)
|
||||
}
|
||||
}
|
||||
|
||||
fn report_peer(&self, who: sc_network::PeerId, cost_benefit: sc_network::ReputationChange) {
|
||||
let _ = self.sender.unbounded_send(Event::Report(who, cost_benefit));
|
||||
impl NetworkNotification for TestNetwork {
|
||||
fn write_notification(&self, target: PeerId, _protocol: Cow<'static, str>, message: Vec<u8>) {
|
||||
let _ = self.sender.unbounded_send(Event::WriteNotification(target, message));
|
||||
}
|
||||
|
||||
fn add_set_reserved(&self, _: PeerId, _: Cow<'static, str>) {}
|
||||
|
||||
fn remove_set_reserved(&self, _: PeerId, _: Cow<'static, str>) {}
|
||||
|
||||
fn disconnect_peer(&self, _: PeerId, _: Cow<'static, str>) {}
|
||||
|
||||
fn write_notification(&self, who: PeerId, _: Cow<'static, str>, message: Vec<u8>) {
|
||||
let _ = self.sender.unbounded_send(Event::WriteNotification(who, message));
|
||||
}
|
||||
|
||||
fn announce(&self, block: Hash, _associated_data: Option<Vec<u8>>) {
|
||||
let _ = self.sender.unbounded_send(Event::Announce(block));
|
||||
fn notification_sender(
|
||||
&self,
|
||||
_target: PeerId,
|
||||
_protocol: Cow<'static, str>,
|
||||
) -> Result<Box<dyn NotificationSender>, NotificationSenderError> {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
impl super::Network<Block> for TestNetwork {
|
||||
fn set_sync_fork_request(
|
||||
&self,
|
||||
_peers: Vec<sc_network::PeerId>,
|
||||
_hash: Hash,
|
||||
_number: NumberFor<Block>,
|
||||
) {
|
||||
impl NetworkBlock<Hash, NumberFor<Block>> for TestNetwork {
|
||||
fn announce_block(&self, hash: Hash, _data: Option<Vec<u8>>) {
|
||||
let _ = self.sender.unbounded_send(Event::Announce(hash));
|
||||
}
|
||||
|
||||
fn new_best_block_imported(&self, _hash: Hash, _number: NumberFor<Block>) {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
impl NetworkSyncForkRequest<Hash, NumberFor<Block>> for TestNetwork {
|
||||
fn set_sync_fork_request(&self, _peers: Vec<PeerId>, _hash: Hash, _number: NumberFor<Block>) {}
|
||||
}
|
||||
|
||||
impl sc_network_gossip::ValidatorContext<Block> for TestNetwork {
|
||||
@@ -93,8 +174,8 @@ impl sc_network_gossip::ValidatorContext<Block> for TestNetwork {
|
||||
|
||||
fn broadcast_message(&mut self, _: Hash, _: Vec<u8>, _: bool) {}
|
||||
|
||||
fn send_message(&mut self, who: &sc_network::PeerId, data: Vec<u8>) {
|
||||
<Self as sc_network_gossip::Network<Block>>::write_notification(
|
||||
fn send_message(&mut self, who: &PeerId, data: Vec<u8>) {
|
||||
<Self as NetworkNotification>::write_notification(
|
||||
self,
|
||||
who.clone(),
|
||||
grandpa_protocol_name::NAME.into(),
|
||||
@@ -102,7 +183,7 @@ impl sc_network_gossip::ValidatorContext<Block> for TestNetwork {
|
||||
);
|
||||
}
|
||||
|
||||
fn send_topic(&mut self, _: &sc_network::PeerId, _: Hash, _: bool) {}
|
||||
fn send_topic(&mut self, _: &PeerId, _: Hash, _: bool) {}
|
||||
}
|
||||
|
||||
pub(crate) struct Tester {
|
||||
@@ -207,8 +288,8 @@ struct NoopContext;
|
||||
impl sc_network_gossip::ValidatorContext<Block> for NoopContext {
|
||||
fn broadcast_topic(&mut self, _: Hash, _: bool) {}
|
||||
fn broadcast_message(&mut self, _: Hash, _: Vec<u8>, _: bool) {}
|
||||
fn send_message(&mut self, _: &sc_network::PeerId, _: Vec<u8>) {}
|
||||
fn send_topic(&mut self, _: &sc_network::PeerId, _: Hash, _: bool) {}
|
||||
fn send_message(&mut self, _: &PeerId, _: Vec<u8>) {}
|
||||
fn send_topic(&mut self, _: &PeerId, _: Hash, _: bool) {}
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -252,7 +333,7 @@ fn good_commit_leads_to_relay() {
|
||||
})
|
||||
.encode();
|
||||
|
||||
let id = sc_network::PeerId::random();
|
||||
let id = PeerId::random();
|
||||
let global_topic = super::global_topic::<Block>(set_id);
|
||||
|
||||
let test = make_test_network()
|
||||
@@ -301,7 +382,7 @@ fn good_commit_leads_to_relay() {
|
||||
});
|
||||
|
||||
// Add a random peer which will be the recipient of this message
|
||||
let receiver_id = sc_network::PeerId::random();
|
||||
let receiver_id = PeerId::random();
|
||||
let _ = sender.unbounded_send(NetworkEvent::NotificationStreamOpened {
|
||||
remote: receiver_id.clone(),
|
||||
protocol: grandpa_protocol_name::NAME.into(),
|
||||
@@ -403,7 +484,7 @@ fn bad_commit_leads_to_report() {
|
||||
})
|
||||
.encode();
|
||||
|
||||
let id = sc_network::PeerId::random();
|
||||
let id = PeerId::random();
|
||||
let global_topic = super::global_topic::<Block>(set_id);
|
||||
|
||||
let test = make_test_network()
|
||||
@@ -484,7 +565,7 @@ fn bad_commit_leads_to_report() {
|
||||
|
||||
#[test]
|
||||
fn peer_with_higher_view_leads_to_catch_up_request() {
|
||||
let id = sc_network::PeerId::random();
|
||||
let id = PeerId::random();
|
||||
|
||||
let (tester, mut net) = make_test_network();
|
||||
let test = tester
|
||||
|
||||
@@ -19,7 +19,7 @@ futures-timer = "3.0.1"
|
||||
log = "0.4.17"
|
||||
parity-util-mem = { version = "0.11.0", default-features = false, features = ["primitive-types"] }
|
||||
sc-client-api = { version = "4.0.0-dev", path = "../api" }
|
||||
sc-network = { version = "0.10.0-dev", path = "../network" }
|
||||
sc-network-common = { version = "0.10.0-dev", path = "../network/common" }
|
||||
sc-transaction-pool-api = { version = "4.0.0-dev", path = "../transaction-pool/api" }
|
||||
sp-blockchain = { version = "4.0.0-dev", path = "../../primitives/blockchain" }
|
||||
sp-runtime = { version = "6.0.0", path = "../../primitives/runtime" }
|
||||
|
||||
@@ -20,7 +20,13 @@ use crate::OutputFormat;
|
||||
use ansi_term::Colour;
|
||||
use log::info;
|
||||
use sc_client_api::ClientInfo;
|
||||
use sc_network::{NetworkStatus, SyncState, WarpSyncPhase, WarpSyncProgress};
|
||||
use sc_network_common::{
|
||||
service::NetworkStatus,
|
||||
sync::{
|
||||
warp::{WarpSyncPhase, WarpSyncProgress},
|
||||
SyncState,
|
||||
},
|
||||
};
|
||||
use sp_runtime::traits::{Block as BlockT, CheckedDiv, NumberFor, Saturating, Zero};
|
||||
use std::{fmt, time::Instant};
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ use futures_timer::Delay;
|
||||
use log::{debug, info, trace};
|
||||
use parity_util_mem::MallocSizeOf;
|
||||
use sc_client_api::{BlockchainEvents, UsageProvider};
|
||||
use sc_network::NetworkService;
|
||||
use sc_network_common::service::NetworkStatusProvider;
|
||||
use sc_transaction_pool_api::TransactionPool;
|
||||
use sp_blockchain::HeaderMetadata;
|
||||
use sp_runtime::traits::{Block as BlockT, Header};
|
||||
@@ -53,12 +53,13 @@ impl Default for OutputFormat {
|
||||
}
|
||||
|
||||
/// Builds the informant and returns a `Future` that drives the informant.
|
||||
pub async fn build<B: BlockT, C, P>(
|
||||
pub async fn build<B: BlockT, C, N, P>(
|
||||
client: Arc<C>,
|
||||
network: Arc<NetworkService<B, <B as BlockT>::Hash>>,
|
||||
network: N,
|
||||
pool: Arc<P>,
|
||||
format: OutputFormat,
|
||||
) where
|
||||
N: NetworkStatusProvider<B>,
|
||||
C: UsageProvider<B> + HeaderMetadata<B> + BlockchainEvents<B>,
|
||||
<C as HeaderMetadata<B>>::Error: Display,
|
||||
P: TransactionPool + MallocSizeOf,
|
||||
|
||||
@@ -23,6 +23,7 @@ lru = "0.7.5"
|
||||
tracing = "0.1.29"
|
||||
prometheus-endpoint = { package = "substrate-prometheus-endpoint", version = "0.10.0-dev", path = "../../utils/prometheus" }
|
||||
sc-network = { version = "0.10.0-dev", path = "../network" }
|
||||
sc-network-common = { version = "0.10.0-dev", path = "../network/common" }
|
||||
sp-runtime = { version = "6.0.0", path = "../../primitives/runtime" }
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
@@ -21,7 +21,8 @@ use crate::{
|
||||
Network, Validator,
|
||||
};
|
||||
|
||||
use sc_network::{Event, ReputationChange};
|
||||
use sc_network::ReputationChange;
|
||||
use sc_network_common::protocol::event::Event;
|
||||
|
||||
use futures::{
|
||||
channel::mpsc::{channel, Receiver, Sender},
|
||||
@@ -85,7 +86,7 @@ impl<B: BlockT> GossipEngine<B> {
|
||||
B: 'static,
|
||||
{
|
||||
let protocol = protocol.into();
|
||||
let network_event_stream = network.event_stream();
|
||||
let network_event_stream = network.event_stream("network-gossip");
|
||||
|
||||
GossipEngine {
|
||||
state_machine: ConsensusGossip::new(validator, protocol.clone(), metrics_registry),
|
||||
@@ -162,7 +163,7 @@ impl<B: BlockT> GossipEngine<B> {
|
||||
/// Note: this method isn't strictly related to gossiping and should eventually be moved
|
||||
/// somewhere else.
|
||||
pub fn announce(&self, block: B::Hash, associated_data: Option<Vec<u8>>) {
|
||||
self.network.announce(block, associated_data);
|
||||
self.network.announce_block(block, associated_data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,7 +182,10 @@ impl<B: BlockT> Future for GossipEngine<B> {
|
||||
this.network.add_set_reserved(remote, this.protocol.clone());
|
||||
},
|
||||
Event::SyncDisconnected { remote } => {
|
||||
this.network.remove_set_reserved(remote, this.protocol.clone());
|
||||
this.network.remove_peers_from_reserved_set(
|
||||
this.protocol.clone(),
|
||||
vec![remote],
|
||||
);
|
||||
},
|
||||
Event::NotificationStreamOpened { remote, protocol, role, .. } => {
|
||||
if protocol != this.protocol {
|
||||
@@ -304,7 +308,7 @@ impl<B: BlockT> futures::future::FusedFuture for GossipEngine<B> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{ValidationResult, ValidatorContext};
|
||||
use crate::{multiaddr::Multiaddr, ValidationResult, ValidatorContext};
|
||||
use async_std::task::spawn;
|
||||
use futures::{
|
||||
channel::mpsc::{unbounded, UnboundedSender},
|
||||
@@ -312,10 +316,20 @@ mod tests {
|
||||
future::poll_fn,
|
||||
};
|
||||
use quickcheck::{Arbitrary, Gen, QuickCheck};
|
||||
use sc_network::ObservedRole;
|
||||
use sp_runtime::{testing::H256, traits::Block as BlockT};
|
||||
use sc_network_common::{
|
||||
protocol::event::ObservedRole,
|
||||
service::{
|
||||
NetworkBlock, NetworkEventStream, NetworkNotification, NetworkPeers,
|
||||
NotificationSender, NotificationSenderError,
|
||||
},
|
||||
};
|
||||
use sp_runtime::{
|
||||
testing::H256,
|
||||
traits::{Block as BlockT, NumberFor},
|
||||
};
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
collections::HashSet,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
use substrate_test_runtime_client::runtime::Block;
|
||||
@@ -330,29 +344,119 @@ mod tests {
|
||||
event_senders: Vec<UnboundedSender<Event>>,
|
||||
}
|
||||
|
||||
impl<B: BlockT> Network<B> for TestNetwork {
|
||||
fn event_stream(&self) -> Pin<Box<dyn Stream<Item = Event> + Send>> {
|
||||
impl NetworkPeers for TestNetwork {
|
||||
fn set_authorized_peers(&self, _peers: HashSet<PeerId>) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn set_authorized_only(&self, _reserved_only: bool) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn add_known_address(&self, _peer_id: PeerId, _addr: Multiaddr) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn report_peer(&self, _who: PeerId, _cost_benefit: ReputationChange) {}
|
||||
|
||||
fn disconnect_peer(&self, _who: PeerId, _protocol: Cow<'static, str>) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn accept_unreserved_peers(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn deny_unreserved_peers(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn add_reserved_peer(&self, _peer: String) -> Result<(), String> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn remove_reserved_peer(&self, _peer_id: PeerId) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn set_reserved_peers(
|
||||
&self,
|
||||
_protocol: Cow<'static, str>,
|
||||
_peers: HashSet<Multiaddr>,
|
||||
) -> Result<(), String> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn add_peers_to_reserved_set(
|
||||
&self,
|
||||
_protocol: Cow<'static, str>,
|
||||
_peers: HashSet<Multiaddr>,
|
||||
) -> Result<(), String> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn remove_peers_from_reserved_set(
|
||||
&self,
|
||||
_protocol: Cow<'static, str>,
|
||||
_peers: Vec<PeerId>,
|
||||
) {
|
||||
}
|
||||
|
||||
fn add_to_peers_set(
|
||||
&self,
|
||||
_protocol: Cow<'static, str>,
|
||||
_peers: HashSet<Multiaddr>,
|
||||
) -> Result<(), String> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn remove_from_peers_set(&self, _protocol: Cow<'static, str>, _peers: Vec<PeerId>) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn sync_num_connected(&self) -> usize {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
impl NetworkEventStream for TestNetwork {
|
||||
fn event_stream(&self, _name: &'static str) -> Pin<Box<dyn Stream<Item = Event> + Send>> {
|
||||
let (tx, rx) = unbounded();
|
||||
self.inner.lock().unwrap().event_senders.push(tx);
|
||||
|
||||
Box::pin(rx)
|
||||
}
|
||||
}
|
||||
|
||||
fn report_peer(&self, _: PeerId, _: ReputationChange) {}
|
||||
|
||||
fn disconnect_peer(&self, _: PeerId, _: Cow<'static, str>) {
|
||||
impl NetworkNotification for TestNetwork {
|
||||
fn write_notification(
|
||||
&self,
|
||||
_target: PeerId,
|
||||
_protocol: Cow<'static, str>,
|
||||
_message: Vec<u8>,
|
||||
) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn add_set_reserved(&self, _: PeerId, _: Cow<'static, str>) {}
|
||||
fn notification_sender(
|
||||
&self,
|
||||
_target: PeerId,
|
||||
_protocol: Cow<'static, str>,
|
||||
) -> Result<Box<dyn NotificationSender>, NotificationSenderError> {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_set_reserved(&self, _: PeerId, _: Cow<'static, str>) {}
|
||||
|
||||
fn write_notification(&self, _: PeerId, _: Cow<'static, str>, _: Vec<u8>) {
|
||||
impl NetworkBlock<<Block as BlockT>::Hash, NumberFor<Block>> for TestNetwork {
|
||||
fn announce_block(&self, _hash: <Block as BlockT>::Hash, _data: Option<Vec<u8>>) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn announce(&self, _: B::Hash, _: Option<Vec<u8>>) {
|
||||
fn new_best_block_imported(
|
||||
&self,
|
||||
_hash: <Block as BlockT>::Hash,
|
||||
_number: NumberFor<Block>,
|
||||
) {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,9 +41,9 @@
|
||||
//! messages.
|
||||
//!
|
||||
//! The [`GossipEngine`] will automatically use [`Network::add_set_reserved`] and
|
||||
//! [`Network::remove_set_reserved`] to maintain a set of peers equal to the set of peers the
|
||||
//! node is syncing from. See the documentation of `sc-network` for more explanations about the
|
||||
//! concepts of peer sets.
|
||||
//! [`NetworkPeers::remove_peers_from_reserved_set`] to maintain a set of peers equal to the set of
|
||||
//! peers the node is syncing from. See the documentation of `sc-network` for more explanations
|
||||
//! about the concepts of peer sets.
|
||||
//!
|
||||
//! # What is a validator?
|
||||
//!
|
||||
@@ -67,74 +67,35 @@ pub use self::{
|
||||
validator::{DiscardAll, MessageIntent, ValidationResult, Validator, ValidatorContext},
|
||||
};
|
||||
|
||||
use futures::prelude::*;
|
||||
use sc_network::{multiaddr, Event, ExHashT, NetworkService, PeerId, ReputationChange};
|
||||
use sp_runtime::traits::Block as BlockT;
|
||||
use std::{borrow::Cow, iter, pin::Pin, sync::Arc};
|
||||
use sc_network::{multiaddr, PeerId};
|
||||
use sc_network_common::service::{
|
||||
NetworkBlock, NetworkEventStream, NetworkNotification, NetworkPeers,
|
||||
};
|
||||
use sp_runtime::traits::{Block as BlockT, NumberFor};
|
||||
use std::{borrow::Cow, iter};
|
||||
|
||||
mod bridge;
|
||||
mod state_machine;
|
||||
mod validator;
|
||||
|
||||
/// Abstraction over a network.
|
||||
pub trait Network<B: BlockT> {
|
||||
/// Returns a stream of events representing what happens on the network.
|
||||
fn event_stream(&self) -> Pin<Box<dyn Stream<Item = Event> + Send>>;
|
||||
|
||||
/// Adjust the reputation of a node.
|
||||
fn report_peer(&self, peer_id: PeerId, reputation: ReputationChange);
|
||||
|
||||
/// Adds the peer to the set of peers to be connected to with this protocol.
|
||||
fn add_set_reserved(&self, who: PeerId, protocol: Cow<'static, str>);
|
||||
|
||||
/// Removes the peer from the set of peers to be connected to with this protocol.
|
||||
fn remove_set_reserved(&self, who: PeerId, protocol: Cow<'static, str>);
|
||||
|
||||
/// Force-disconnect a peer.
|
||||
fn disconnect_peer(&self, who: PeerId, protocol: Cow<'static, str>);
|
||||
|
||||
/// Send a notification to a peer.
|
||||
fn write_notification(&self, who: PeerId, protocol: Cow<'static, str>, message: Vec<u8>);
|
||||
|
||||
/// Notify everyone we're connected to that we have the given block.
|
||||
///
|
||||
/// Note: this method isn't strictly related to gossiping and should eventually be moved
|
||||
/// somewhere else.
|
||||
fn announce(&self, block: B::Hash, associated_data: Option<Vec<u8>>);
|
||||
}
|
||||
|
||||
impl<B: BlockT, H: ExHashT> Network<B> for Arc<NetworkService<B, H>> {
|
||||
fn event_stream(&self) -> Pin<Box<dyn Stream<Item = Event> + Send>> {
|
||||
Box::pin(NetworkService::event_stream(self, "network-gossip"))
|
||||
}
|
||||
|
||||
fn report_peer(&self, peer_id: PeerId, reputation: ReputationChange) {
|
||||
NetworkService::report_peer(self, peer_id, reputation);
|
||||
}
|
||||
|
||||
pub trait Network<B: BlockT>:
|
||||
NetworkPeers + NetworkEventStream + NetworkNotification + NetworkBlock<B::Hash, NumberFor<B>>
|
||||
{
|
||||
fn add_set_reserved(&self, who: PeerId, protocol: Cow<'static, str>) {
|
||||
let addr =
|
||||
iter::once(multiaddr::Protocol::P2p(who.into())).collect::<multiaddr::Multiaddr>();
|
||||
let result =
|
||||
NetworkService::add_peers_to_reserved_set(self, protocol, iter::once(addr).collect());
|
||||
let result = self.add_peers_to_reserved_set(protocol, iter::once(addr).collect());
|
||||
if let Err(err) = result {
|
||||
log::error!(target: "gossip", "add_set_reserved failed: {}", err);
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_set_reserved(&self, who: PeerId, protocol: Cow<'static, str>) {
|
||||
NetworkService::remove_peers_from_reserved_set(self, protocol, iter::once(who).collect());
|
||||
}
|
||||
|
||||
fn disconnect_peer(&self, who: PeerId, protocol: Cow<'static, str>) {
|
||||
NetworkService::disconnect_peer(self, who, protocol)
|
||||
}
|
||||
|
||||
fn write_notification(&self, who: PeerId, protocol: Cow<'static, str>, message: Vec<u8>) {
|
||||
NetworkService::write_notification(self, who, protocol, message)
|
||||
}
|
||||
|
||||
fn announce(&self, block: B::Hash, associated_data: Option<Vec<u8>>) {
|
||||
NetworkService::announce_block(self, block, associated_data)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, B: BlockT> Network<B> for T where
|
||||
T: NetworkPeers
|
||||
+ NetworkEventStream
|
||||
+ NetworkNotification
|
||||
+ NetworkBlock<B::Hash, NumberFor<B>>
|
||||
{
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ use ahash::AHashSet;
|
||||
use libp2p::PeerId;
|
||||
use lru::LruCache;
|
||||
use prometheus_endpoint::{register, Counter, PrometheusError, Registry, U64};
|
||||
use sc_network::ObservedRole;
|
||||
use sc_network_common::protocol::event::ObservedRole;
|
||||
use sp_runtime::traits::{Block as BlockT, Hash, HashFor};
|
||||
use std::{borrow::Cow, collections::HashMap, iter, sync::Arc, time, time::Instant};
|
||||
|
||||
@@ -511,11 +511,23 @@ impl Metrics {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::multiaddr::Multiaddr;
|
||||
use futures::prelude::*;
|
||||
use sc_network::{Event, ReputationChange};
|
||||
use sp_runtime::testing::{Block as RawBlock, ExtrinsicWrapper, H256};
|
||||
use sc_network::ReputationChange;
|
||||
use sc_network_common::{
|
||||
protocol::event::Event,
|
||||
service::{
|
||||
NetworkBlock, NetworkEventStream, NetworkNotification, NetworkPeers,
|
||||
NotificationSender, NotificationSenderError,
|
||||
},
|
||||
};
|
||||
use sp_runtime::{
|
||||
testing::{Block as RawBlock, ExtrinsicWrapper, H256},
|
||||
traits::NumberFor,
|
||||
};
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
collections::HashSet,
|
||||
pin::Pin,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
@@ -569,28 +581,118 @@ mod tests {
|
||||
peer_reports: Vec<(PeerId, ReputationChange)>,
|
||||
}
|
||||
|
||||
impl<B: BlockT> Network<B> for NoOpNetwork {
|
||||
fn event_stream(&self) -> Pin<Box<dyn Stream<Item = Event> + Send>> {
|
||||
impl NetworkPeers for NoOpNetwork {
|
||||
fn set_authorized_peers(&self, _peers: HashSet<PeerId>) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn report_peer(&self, peer_id: PeerId, reputation_change: ReputationChange) {
|
||||
self.inner.lock().unwrap().peer_reports.push((peer_id, reputation_change));
|
||||
}
|
||||
|
||||
fn disconnect_peer(&self, _: PeerId, _: Cow<'static, str>) {
|
||||
fn set_authorized_only(&self, _reserved_only: bool) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn add_set_reserved(&self, _: PeerId, _: Cow<'static, str>) {}
|
||||
|
||||
fn remove_set_reserved(&self, _: PeerId, _: Cow<'static, str>) {}
|
||||
|
||||
fn write_notification(&self, _: PeerId, _: Cow<'static, str>, _: Vec<u8>) {
|
||||
fn add_known_address(&self, _peer_id: PeerId, _addr: Multiaddr) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn announce(&self, _: B::Hash, _: Option<Vec<u8>>) {
|
||||
fn report_peer(&self, who: PeerId, cost_benefit: ReputationChange) {
|
||||
self.inner.lock().unwrap().peer_reports.push((who, cost_benefit));
|
||||
}
|
||||
|
||||
fn disconnect_peer(&self, _who: PeerId, _protocol: Cow<'static, str>) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn accept_unreserved_peers(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn deny_unreserved_peers(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn add_reserved_peer(&self, _peer: String) -> Result<(), String> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn remove_reserved_peer(&self, _peer_id: PeerId) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn set_reserved_peers(
|
||||
&self,
|
||||
_protocol: Cow<'static, str>,
|
||||
_peers: HashSet<Multiaddr>,
|
||||
) -> Result<(), String> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn add_peers_to_reserved_set(
|
||||
&self,
|
||||
_protocol: Cow<'static, str>,
|
||||
_peers: HashSet<Multiaddr>,
|
||||
) -> Result<(), String> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn remove_peers_from_reserved_set(
|
||||
&self,
|
||||
_protocol: Cow<'static, str>,
|
||||
_peers: Vec<PeerId>,
|
||||
) {
|
||||
}
|
||||
|
||||
fn add_to_peers_set(
|
||||
&self,
|
||||
_protocol: Cow<'static, str>,
|
||||
_peers: HashSet<Multiaddr>,
|
||||
) -> Result<(), String> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn remove_from_peers_set(&self, _protocol: Cow<'static, str>, _peers: Vec<PeerId>) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn sync_num_connected(&self) -> usize {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
impl NetworkEventStream for NoOpNetwork {
|
||||
fn event_stream(&self, _name: &'static str) -> Pin<Box<dyn Stream<Item = Event> + Send>> {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
impl NetworkNotification for NoOpNetwork {
|
||||
fn write_notification(
|
||||
&self,
|
||||
_target: PeerId,
|
||||
_protocol: Cow<'static, str>,
|
||||
_message: Vec<u8>,
|
||||
) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn notification_sender(
|
||||
&self,
|
||||
_target: PeerId,
|
||||
_protocol: Cow<'static, str>,
|
||||
) -> Result<Box<dyn NotificationSender>, NotificationSenderError> {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
impl NetworkBlock<<Block as BlockT>::Hash, NumberFor<Block>> for NoOpNetwork {
|
||||
fn announce_block(&self, _hash: <Block as BlockT>::Hash, _data: Option<Vec<u8>>) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn new_best_block_imported(
|
||||
&self,
|
||||
_hash: <Block as BlockT>::Hash,
|
||||
_number: NumberFor<Block>,
|
||||
) {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
// 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 sc_network::{ObservedRole, PeerId};
|
||||
use sc_network::PeerId;
|
||||
use sc_network_common::protocol::event::ObservedRole;
|
||||
use sp_runtime::traits::Block as BlockT;
|
||||
|
||||
/// Validates consensus messages.
|
||||
|
||||
@@ -17,7 +17,9 @@ targets = ["x86_64-unknown-linux-gnu"]
|
||||
prost-build = "0.10"
|
||||
|
||||
[dependencies]
|
||||
async-trait = "0.1.50"
|
||||
bitflags = "1.3.2"
|
||||
bytes = "1"
|
||||
codec = { package = "parity-scale-codec", version = "3.0.0", features = [
|
||||
"derive",
|
||||
] }
|
||||
@@ -29,3 +31,4 @@ sc-peerset = { version = "4.0.0-dev", path = "../../peerset" }
|
||||
sp-consensus = { version = "0.10.0-dev", path = "../../../primitives/consensus/common" }
|
||||
sp-finality-grandpa = { version = "4.0.0-dev", path = "../../../primitives/finality-grandpa" }
|
||||
sp-runtime = { version = "6.0.0", path = "../../../primitives/runtime" }
|
||||
thiserror = "1.0"
|
||||
|
||||
@@ -20,5 +20,7 @@
|
||||
|
||||
pub mod config;
|
||||
pub mod message;
|
||||
pub mod protocol;
|
||||
pub mod request_responses;
|
||||
pub mod service;
|
||||
pub mod sync;
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
// 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/>.
|
||||
|
||||
pub mod event;
|
||||
+2
-2
@@ -67,14 +67,14 @@ pub enum Event {
|
||||
remote: PeerId,
|
||||
/// The concerned protocol. Each protocol uses a different substream.
|
||||
/// This is always equal to the value of
|
||||
/// [`crate::config::NonDefaultSetConfig::notifications_protocol`] of one of the
|
||||
/// `sc_network::config::NonDefaultSetConfig::notifications_protocol` of one of the
|
||||
/// configured sets.
|
||||
protocol: Cow<'static, str>,
|
||||
/// If the negotiation didn't use the main name of the protocol (the one in
|
||||
/// `notifications_protocol`), then this field contains which name has actually been
|
||||
/// used.
|
||||
/// Always contains a value equal to the value in
|
||||
/// [`crate::config::NonDefaultSetConfig::fallback_names`].
|
||||
/// `sc_network::config::NonDefaultSetConfig::fallback_names`.
|
||||
negotiated_fallback: Option<Cow<'static, str>>,
|
||||
/// Role of the remote.
|
||||
role: ObservedRole,
|
||||
@@ -19,7 +19,7 @@
|
||||
//! Collection of generic data structures for request-response protocols.
|
||||
|
||||
use futures::channel::{mpsc, oneshot};
|
||||
use libp2p::PeerId;
|
||||
use libp2p::{request_response::OutboundFailure, PeerId};
|
||||
use sc_peerset::ReputationChange;
|
||||
use std::{borrow::Cow, time::Duration};
|
||||
|
||||
@@ -115,3 +115,40 @@ pub struct OutgoingResponse {
|
||||
/// > written to the buffer managed by the operating system.
|
||||
pub sent_feedback: Option<oneshot::Sender<()>>,
|
||||
}
|
||||
|
||||
/// When sending a request, what to do on a disconnected recipient.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum IfDisconnected {
|
||||
/// Try to connect to the peer.
|
||||
TryConnect,
|
||||
/// Just fail if the destination is not yet connected.
|
||||
ImmediateError,
|
||||
}
|
||||
|
||||
/// Convenience functions for `IfDisconnected`.
|
||||
impl IfDisconnected {
|
||||
/// Shall we connect to a disconnected peer?
|
||||
pub fn should_connect(self) -> bool {
|
||||
match self {
|
||||
Self::TryConnect => true,
|
||||
Self::ImmediateError => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Error in a request.
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum RequestFailure {
|
||||
#[error("We are not currently connected to the requested peer.")]
|
||||
NotConnected,
|
||||
#[error("Given protocol hasn't been registered.")]
|
||||
UnknownProtocol,
|
||||
#[error("Remote has closed the substream before answering, thereby signaling that it considers the request as valid, but refused to answer it.")]
|
||||
Refused,
|
||||
#[error("The remote replied, but the local node is no longer interested in the response.")]
|
||||
Obsolete,
|
||||
/// Problem on the network.
|
||||
#[error("Problem on the network: {0}")]
|
||||
Network(OutboundFailure),
|
||||
}
|
||||
|
||||
@@ -0,0 +1,660 @@
|
||||
// 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 crate::{
|
||||
protocol::event::Event,
|
||||
request_responses::{IfDisconnected, RequestFailure},
|
||||
sync::{warp::WarpSyncProgress, StateDownloadProgress, SyncState},
|
||||
};
|
||||
use futures::{channel::oneshot, Stream};
|
||||
pub use libp2p::{identity::error::SigningError, kad::record::Key as KademliaKey};
|
||||
use libp2p::{Multiaddr, PeerId};
|
||||
use sc_peerset::ReputationChange;
|
||||
pub use signature::Signature;
|
||||
use sp_runtime::traits::{Block as BlockT, NumberFor};
|
||||
use std::{borrow::Cow, collections::HashSet, future::Future, pin::Pin, sync::Arc};
|
||||
|
||||
mod signature;
|
||||
|
||||
/// Signer with network identity
|
||||
pub trait NetworkSigner {
|
||||
/// Signs the message with the `KeyPair` that defines the local [`PeerId`].
|
||||
fn sign_with_local_identity(&self, msg: impl AsRef<[u8]>) -> Result<Signature, SigningError>;
|
||||
}
|
||||
|
||||
impl<T> NetworkSigner for Arc<T>
|
||||
where
|
||||
T: ?Sized,
|
||||
T: NetworkSigner,
|
||||
{
|
||||
fn sign_with_local_identity(&self, msg: impl AsRef<[u8]>) -> Result<Signature, SigningError> {
|
||||
T::sign_with_local_identity(self, msg)
|
||||
}
|
||||
}
|
||||
|
||||
/// Provides access to the networking DHT.
|
||||
pub trait NetworkDHTProvider {
|
||||
/// Start getting a value from the DHT.
|
||||
fn get_value(&self, key: &KademliaKey);
|
||||
|
||||
/// Start putting a value in the DHT.
|
||||
fn put_value(&self, key: KademliaKey, value: Vec<u8>);
|
||||
}
|
||||
|
||||
impl<T> NetworkDHTProvider for Arc<T>
|
||||
where
|
||||
T: ?Sized,
|
||||
T: NetworkDHTProvider,
|
||||
{
|
||||
fn get_value(&self, key: &KademliaKey) {
|
||||
T::get_value(self, key)
|
||||
}
|
||||
|
||||
fn put_value(&self, key: KademliaKey, value: Vec<u8>) {
|
||||
T::put_value(self, key, value)
|
||||
}
|
||||
}
|
||||
|
||||
/// Provides an ability to set a fork sync request for a particular block.
|
||||
pub trait NetworkSyncForkRequest<BlockHash, BlockNumber> {
|
||||
/// Notifies the sync service to try and sync the given block from the given
|
||||
/// peers.
|
||||
///
|
||||
/// If the given vector of peers is empty then the underlying implementation
|
||||
/// should make a best effort to fetch the block from any peers it is
|
||||
/// connected to (NOTE: this assumption will change in the future #3629).
|
||||
fn set_sync_fork_request(&self, peers: Vec<PeerId>, hash: BlockHash, number: BlockNumber);
|
||||
}
|
||||
|
||||
impl<T, BlockHash, BlockNumber> NetworkSyncForkRequest<BlockHash, BlockNumber> for Arc<T>
|
||||
where
|
||||
T: ?Sized,
|
||||
T: NetworkSyncForkRequest<BlockHash, BlockNumber>,
|
||||
{
|
||||
fn set_sync_fork_request(&self, peers: Vec<PeerId>, hash: BlockHash, number: BlockNumber) {
|
||||
T::set_sync_fork_request(self, peers, hash, number)
|
||||
}
|
||||
}
|
||||
|
||||
/// Overview status of the network.
|
||||
#[derive(Clone)]
|
||||
pub struct NetworkStatus<B: BlockT> {
|
||||
/// Current global sync state.
|
||||
pub sync_state: SyncState,
|
||||
/// Target sync block number.
|
||||
pub best_seen_block: Option<NumberFor<B>>,
|
||||
/// Number of peers participating in syncing.
|
||||
pub num_sync_peers: u32,
|
||||
/// Total number of connected peers
|
||||
pub num_connected_peers: usize,
|
||||
/// Total number of active peers.
|
||||
pub num_active_peers: usize,
|
||||
/// The total number of bytes received.
|
||||
pub total_bytes_inbound: u64,
|
||||
/// The total number of bytes sent.
|
||||
pub total_bytes_outbound: u64,
|
||||
/// State sync in progress.
|
||||
pub state_sync: Option<StateDownloadProgress>,
|
||||
/// Warp sync in progress.
|
||||
pub warp_sync: Option<WarpSyncProgress<B>>,
|
||||
}
|
||||
|
||||
/// Provides high-level status information about network.
|
||||
#[async_trait::async_trait]
|
||||
pub trait NetworkStatusProvider<Block: BlockT> {
|
||||
/// High-level network status information.
|
||||
///
|
||||
/// Returns an error if the `NetworkWorker` is no longer running.
|
||||
async fn status(&self) -> Result<NetworkStatus<Block>, ()>;
|
||||
}
|
||||
|
||||
// Manual implementation to avoid extra boxing here
|
||||
impl<T, Block: BlockT> NetworkStatusProvider<Block> for Arc<T>
|
||||
where
|
||||
T: ?Sized,
|
||||
T: NetworkStatusProvider<Block>,
|
||||
{
|
||||
fn status<'life0, 'async_trait>(
|
||||
&'life0 self,
|
||||
) -> Pin<Box<dyn Future<Output = Result<NetworkStatus<Block>, ()>> + Send + 'async_trait>>
|
||||
where
|
||||
'life0: 'async_trait,
|
||||
Self: 'async_trait,
|
||||
{
|
||||
T::status(self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Provides low-level API for manipulating network peers.
|
||||
pub trait NetworkPeers {
|
||||
/// Set authorized peers.
|
||||
///
|
||||
/// Need a better solution to manage authorized peers, but now just use reserved peers for
|
||||
/// prototyping.
|
||||
fn set_authorized_peers(&self, peers: HashSet<PeerId>);
|
||||
|
||||
/// Set authorized_only flag.
|
||||
///
|
||||
/// Need a better solution to decide authorized_only, but now just use reserved_only flag for
|
||||
/// prototyping.
|
||||
fn set_authorized_only(&self, reserved_only: bool);
|
||||
|
||||
/// Adds an address known to a node.
|
||||
fn add_known_address(&self, peer_id: PeerId, addr: Multiaddr);
|
||||
|
||||
/// Report a given peer as either beneficial (+) or costly (-) according to the
|
||||
/// given scalar.
|
||||
fn report_peer(&self, who: PeerId, cost_benefit: ReputationChange);
|
||||
|
||||
/// Disconnect from a node as soon as possible.
|
||||
///
|
||||
/// This triggers the same effects as if the connection had closed itself spontaneously.
|
||||
///
|
||||
/// See also [`NetworkPeers::remove_from_peers_set`], which has the same effect but also
|
||||
/// prevents the local node from re-establishing an outgoing substream to this peer until it
|
||||
/// is added again.
|
||||
fn disconnect_peer(&self, who: PeerId, protocol: Cow<'static, str>);
|
||||
|
||||
/// Connect to unreserved peers and allow unreserved peers to connect for syncing purposes.
|
||||
fn accept_unreserved_peers(&self);
|
||||
|
||||
/// Disconnect from unreserved peers and deny new unreserved peers to connect for syncing
|
||||
/// purposes.
|
||||
fn deny_unreserved_peers(&self);
|
||||
|
||||
/// Adds a `PeerId` and its address as reserved. The string should encode the address
|
||||
/// and peer ID of the remote node.
|
||||
///
|
||||
/// Returns an `Err` if the given string is not a valid multiaddress
|
||||
/// or contains an invalid peer ID (which includes the local peer ID).
|
||||
fn add_reserved_peer(&self, peer: String) -> Result<(), String>;
|
||||
|
||||
/// Removes a `PeerId` from the list of reserved peers.
|
||||
fn remove_reserved_peer(&self, peer_id: PeerId);
|
||||
|
||||
/// Sets the reserved set of a protocol to the given set of peers.
|
||||
///
|
||||
/// Each `Multiaddr` must end with a `/p2p/` component containing the `PeerId`. It can also
|
||||
/// consist of only `/p2p/<peerid>`.
|
||||
///
|
||||
/// The node will start establishing/accepting connections and substreams to/from peers in this
|
||||
/// set, if it doesn't have any substream open with them yet.
|
||||
///
|
||||
/// Note however, if a call to this function results in less peers on the reserved set, they
|
||||
/// will not necessarily get disconnected (depending on available free slots in the peer set).
|
||||
/// If you want to also disconnect those removed peers, you will have to call
|
||||
/// `remove_from_peers_set` on those in addition to updating the reserved set. You can omit
|
||||
/// this step if the peer set is in reserved only mode.
|
||||
///
|
||||
/// Returns an `Err` if one of the given addresses is invalid or contains an
|
||||
/// invalid peer ID (which includes the local peer ID).
|
||||
fn set_reserved_peers(
|
||||
&self,
|
||||
protocol: Cow<'static, str>,
|
||||
peers: HashSet<Multiaddr>,
|
||||
) -> Result<(), String>;
|
||||
|
||||
/// Add peers to a peer set.
|
||||
///
|
||||
/// Each `Multiaddr` must end with a `/p2p/` component containing the `PeerId`. It can also
|
||||
/// consist of only `/p2p/<peerid>`.
|
||||
///
|
||||
/// Returns an `Err` if one of the given addresses is invalid or contains an
|
||||
/// invalid peer ID (which includes the local peer ID).
|
||||
fn add_peers_to_reserved_set(
|
||||
&self,
|
||||
protocol: Cow<'static, str>,
|
||||
peers: HashSet<Multiaddr>,
|
||||
) -> Result<(), String>;
|
||||
|
||||
/// Remove peers from a peer set.
|
||||
fn remove_peers_from_reserved_set(&self, protocol: Cow<'static, str>, peers: Vec<PeerId>);
|
||||
|
||||
/// Add a peer to a set of peers.
|
||||
///
|
||||
/// If the set has slots available, it will try to open a substream with this peer.
|
||||
///
|
||||
/// Each `Multiaddr` must end with a `/p2p/` component containing the `PeerId`. It can also
|
||||
/// consist of only `/p2p/<peerid>`.
|
||||
///
|
||||
/// Returns an `Err` if one of the given addresses is invalid or contains an
|
||||
/// invalid peer ID (which includes the local peer ID).
|
||||
fn add_to_peers_set(
|
||||
&self,
|
||||
protocol: Cow<'static, str>,
|
||||
peers: HashSet<Multiaddr>,
|
||||
) -> Result<(), String>;
|
||||
|
||||
/// Remove peers from a peer set.
|
||||
///
|
||||
/// If we currently have an open substream with this peer, it will soon be closed.
|
||||
fn remove_from_peers_set(&self, protocol: Cow<'static, str>, peers: Vec<PeerId>);
|
||||
|
||||
/// Returns the number of peers in the sync peer set we're connected to.
|
||||
fn sync_num_connected(&self) -> usize;
|
||||
}
|
||||
|
||||
// Manual implementation to avoid extra boxing here
|
||||
impl<T> NetworkPeers for Arc<T>
|
||||
where
|
||||
T: ?Sized,
|
||||
T: NetworkPeers,
|
||||
{
|
||||
fn set_authorized_peers(&self, peers: HashSet<PeerId>) {
|
||||
T::set_authorized_peers(self, peers)
|
||||
}
|
||||
|
||||
fn set_authorized_only(&self, reserved_only: bool) {
|
||||
T::set_authorized_only(self, reserved_only)
|
||||
}
|
||||
|
||||
fn add_known_address(&self, peer_id: PeerId, addr: Multiaddr) {
|
||||
T::add_known_address(self, peer_id, addr)
|
||||
}
|
||||
|
||||
fn report_peer(&self, who: PeerId, cost_benefit: ReputationChange) {
|
||||
T::report_peer(self, who, cost_benefit)
|
||||
}
|
||||
|
||||
fn disconnect_peer(&self, who: PeerId, protocol: Cow<'static, str>) {
|
||||
T::disconnect_peer(self, who, protocol)
|
||||
}
|
||||
|
||||
fn accept_unreserved_peers(&self) {
|
||||
T::accept_unreserved_peers(self)
|
||||
}
|
||||
|
||||
fn deny_unreserved_peers(&self) {
|
||||
T::deny_unreserved_peers(self)
|
||||
}
|
||||
|
||||
fn add_reserved_peer(&self, peer: String) -> Result<(), String> {
|
||||
T::add_reserved_peer(self, peer)
|
||||
}
|
||||
|
||||
fn remove_reserved_peer(&self, peer_id: PeerId) {
|
||||
T::remove_reserved_peer(self, peer_id)
|
||||
}
|
||||
|
||||
fn set_reserved_peers(
|
||||
&self,
|
||||
protocol: Cow<'static, str>,
|
||||
peers: HashSet<Multiaddr>,
|
||||
) -> Result<(), String> {
|
||||
T::set_reserved_peers(self, protocol, peers)
|
||||
}
|
||||
|
||||
fn add_peers_to_reserved_set(
|
||||
&self,
|
||||
protocol: Cow<'static, str>,
|
||||
peers: HashSet<Multiaddr>,
|
||||
) -> Result<(), String> {
|
||||
T::add_peers_to_reserved_set(self, protocol, peers)
|
||||
}
|
||||
|
||||
fn remove_peers_from_reserved_set(&self, protocol: Cow<'static, str>, peers: Vec<PeerId>) {
|
||||
T::remove_peers_from_reserved_set(self, protocol, peers)
|
||||
}
|
||||
|
||||
fn add_to_peers_set(
|
||||
&self,
|
||||
protocol: Cow<'static, str>,
|
||||
peers: HashSet<Multiaddr>,
|
||||
) -> Result<(), String> {
|
||||
T::add_to_peers_set(self, protocol, peers)
|
||||
}
|
||||
|
||||
fn remove_from_peers_set(&self, protocol: Cow<'static, str>, peers: Vec<PeerId>) {
|
||||
T::remove_from_peers_set(self, protocol, peers)
|
||||
}
|
||||
|
||||
fn sync_num_connected(&self) -> usize {
|
||||
T::sync_num_connected(self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Provides access to network-level event stream.
|
||||
pub trait NetworkEventStream {
|
||||
/// Returns a stream containing the events that happen on the network.
|
||||
///
|
||||
/// If this method is called multiple times, the events are duplicated.
|
||||
///
|
||||
/// The stream never ends (unless the `NetworkWorker` gets shut down).
|
||||
///
|
||||
/// The name passed is used to identify the channel in the Prometheus metrics. Note that the
|
||||
/// parameter is a `&'static str`, and not a `String`, in order to avoid accidentally having
|
||||
/// an unbounded set of Prometheus metrics, which would be quite bad in terms of memory
|
||||
fn event_stream(&self, name: &'static str) -> Pin<Box<dyn Stream<Item = Event> + Send>>;
|
||||
}
|
||||
|
||||
impl<T> NetworkEventStream for Arc<T>
|
||||
where
|
||||
T: ?Sized,
|
||||
T: NetworkEventStream,
|
||||
{
|
||||
fn event_stream(&self, name: &'static str) -> Pin<Box<dyn Stream<Item = Event> + Send>> {
|
||||
T::event_stream(self, name)
|
||||
}
|
||||
}
|
||||
|
||||
/// Trait for providing information about the local network state
|
||||
pub trait NetworkStateInfo {
|
||||
/// Returns the local external addresses.
|
||||
fn external_addresses(&self) -> Vec<Multiaddr>;
|
||||
|
||||
/// Returns the local Peer ID.
|
||||
fn local_peer_id(&self) -> PeerId;
|
||||
}
|
||||
|
||||
impl<T> NetworkStateInfo for Arc<T>
|
||||
where
|
||||
T: ?Sized,
|
||||
T: NetworkStateInfo,
|
||||
{
|
||||
fn external_addresses(&self) -> Vec<Multiaddr> {
|
||||
T::external_addresses(self)
|
||||
}
|
||||
|
||||
fn local_peer_id(&self) -> PeerId {
|
||||
T::local_peer_id(self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Reserved slot in the notifications buffer, ready to accept data.
|
||||
pub trait NotificationSenderReady {
|
||||
/// Consumes this slots reservation and actually queues the notification.
|
||||
///
|
||||
/// NOTE: Traits can't consume itself, but calling this method second time will return an error.
|
||||
fn send(&mut self, notification: Vec<u8>) -> Result<(), NotificationSenderError>;
|
||||
}
|
||||
|
||||
/// A `NotificationSender` allows for sending notifications to a peer with a chosen protocol.
|
||||
#[async_trait::async_trait]
|
||||
pub trait NotificationSender {
|
||||
/// Returns a future that resolves when the `NotificationSender` is ready to send a
|
||||
/// notification.
|
||||
async fn ready(&self)
|
||||
-> Result<Box<dyn NotificationSenderReady + '_>, NotificationSenderError>;
|
||||
}
|
||||
|
||||
/// Error returned by [`NetworkNotification::notification_sender`].
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum NotificationSenderError {
|
||||
/// The notification receiver has been closed, usually because the underlying connection
|
||||
/// closed.
|
||||
///
|
||||
/// Some of the notifications most recently sent may not have been received. However,
|
||||
/// the peer may still be connected and a new `NotificationSender` for the same
|
||||
/// protocol obtained from [`NetworkNotification::notification_sender`].
|
||||
#[error("The notification receiver has been closed")]
|
||||
Closed,
|
||||
/// Protocol name hasn't been registered.
|
||||
#[error("Protocol name hasn't been registered")]
|
||||
BadProtocol,
|
||||
}
|
||||
|
||||
/// Provides ability to send network notifications.
|
||||
pub trait NetworkNotification {
|
||||
/// Appends a notification to the buffer of pending outgoing notifications with the given peer.
|
||||
/// Has no effect if the notifications channel with this protocol name is not open.
|
||||
///
|
||||
/// If the buffer of pending outgoing notifications with that peer is full, the notification
|
||||
/// is silently dropped and the connection to the remote will start being shut down. This
|
||||
/// happens if you call this method at a higher rate than the rate at which the peer processes
|
||||
/// these notifications, or if the available network bandwidth is too low.
|
||||
///
|
||||
/// For this reason, this method is considered soft-deprecated. You are encouraged to use
|
||||
/// [`NetworkNotification::notification_sender`] instead.
|
||||
///
|
||||
/// > **Note**: The reason why this is a no-op in the situation where we have no channel is
|
||||
/// > that we don't guarantee message delivery anyway. Networking issues can cause
|
||||
/// > connections to drop at any time, and higher-level logic shouldn't differentiate
|
||||
/// > between the remote voluntarily closing a substream or a network error
|
||||
/// > preventing the message from being delivered.
|
||||
///
|
||||
/// The protocol must have been registered with
|
||||
/// `crate::config::NetworkConfiguration::notifications_protocols`.
|
||||
fn write_notification(&self, target: PeerId, protocol: Cow<'static, str>, message: Vec<u8>);
|
||||
|
||||
/// Obtains a [`NotificationSender`] for a connected peer, if it exists.
|
||||
///
|
||||
/// A `NotificationSender` is scoped to a particular connection to the peer that holds
|
||||
/// a receiver. With a `NotificationSender` at hand, sending a notification is done in two
|
||||
/// steps:
|
||||
///
|
||||
/// 1. [`NotificationSender::ready`] is used to wait for the sender to become ready
|
||||
/// for another notification, yielding a [`NotificationSenderReady`] token.
|
||||
/// 2. [`NotificationSenderReady::send`] enqueues the notification for sending. This operation
|
||||
/// can only fail if the underlying notification substream or connection has suddenly closed.
|
||||
///
|
||||
/// An error is returned by [`NotificationSenderReady::send`] if there exists no open
|
||||
/// notifications substream with that combination of peer and protocol, or if the remote
|
||||
/// has asked to close the notifications substream. If that happens, it is guaranteed that an
|
||||
/// [`Event::NotificationStreamClosed`] has been generated on the stream returned by
|
||||
/// [`NetworkEventStream::event_stream`].
|
||||
///
|
||||
/// If the remote requests to close the notifications substream, all notifications successfully
|
||||
/// enqueued using [`NotificationSenderReady::send`] will finish being sent out before the
|
||||
/// substream actually gets closed, but attempting to enqueue more notifications will now
|
||||
/// return an error. It is however possible for the entire connection to be abruptly closed,
|
||||
/// in which case enqueued notifications will be lost.
|
||||
///
|
||||
/// The protocol must have been registered with
|
||||
/// `crate::config::NetworkConfiguration::notifications_protocols`.
|
||||
///
|
||||
/// # Usage
|
||||
///
|
||||
/// This method returns a struct that allows waiting until there is space available in the
|
||||
/// buffer of messages towards the given peer. If the peer processes notifications at a slower
|
||||
/// rate than we send them, this buffer will quickly fill up.
|
||||
///
|
||||
/// As such, you should never do something like this:
|
||||
///
|
||||
/// ```ignore
|
||||
/// // Do NOT do this
|
||||
/// for peer in peers {
|
||||
/// if let Ok(n) = network.notification_sender(peer, ...) {
|
||||
/// if let Ok(s) = n.ready().await {
|
||||
/// let _ = s.send(...);
|
||||
/// }
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Doing so would slow down all peers to the rate of the slowest one. A malicious or
|
||||
/// malfunctioning peer could intentionally process notifications at a very slow rate.
|
||||
///
|
||||
/// Instead, you are encouraged to maintain your own buffer of notifications on top of the one
|
||||
/// maintained by `sc-network`, and use `notification_sender` to progressively send out
|
||||
/// elements from your buffer. If this additional buffer is full (which will happen at some
|
||||
/// point if the peer is too slow to process notifications), appropriate measures can be taken,
|
||||
/// such as removing non-critical notifications from the buffer or disconnecting the peer
|
||||
/// using [`NetworkPeers::disconnect_peer`].
|
||||
///
|
||||
///
|
||||
/// Notifications Per-peer buffer
|
||||
/// broadcast +-------> of notifications +--> `notification_sender` +--> Internet
|
||||
/// ^ (not covered by
|
||||
/// | sc-network)
|
||||
/// +
|
||||
/// Notifications should be dropped
|
||||
/// if buffer is full
|
||||
///
|
||||
///
|
||||
/// See also the `sc-network-gossip` crate for a higher-level way to send notifications.
|
||||
fn notification_sender(
|
||||
&self,
|
||||
target: PeerId,
|
||||
protocol: Cow<'static, str>,
|
||||
) -> Result<Box<dyn NotificationSender>, NotificationSenderError>;
|
||||
}
|
||||
|
||||
impl<T> NetworkNotification for Arc<T>
|
||||
where
|
||||
T: ?Sized,
|
||||
T: NetworkNotification,
|
||||
{
|
||||
fn write_notification(&self, target: PeerId, protocol: Cow<'static, str>, message: Vec<u8>) {
|
||||
T::write_notification(self, target, protocol, message)
|
||||
}
|
||||
|
||||
fn notification_sender(
|
||||
&self,
|
||||
target: PeerId,
|
||||
protocol: Cow<'static, str>,
|
||||
) -> Result<Box<dyn NotificationSender>, NotificationSenderError> {
|
||||
T::notification_sender(self, target, protocol)
|
||||
}
|
||||
}
|
||||
|
||||
/// Provides ability to send network requests.
|
||||
#[async_trait::async_trait]
|
||||
pub trait NetworkRequest {
|
||||
/// Sends a single targeted request to a specific peer. On success, returns the response of
|
||||
/// the peer.
|
||||
///
|
||||
/// Request-response protocols are a way to complement notifications protocols, but
|
||||
/// notifications should remain the default ways of communicating information. For example, a
|
||||
/// peer can announce something through a notification, after which the recipient can obtain
|
||||
/// more information by performing a request.
|
||||
/// As such, call this function with `IfDisconnected::ImmediateError` for `connect`. This way
|
||||
/// you will get an error immediately for disconnected peers, instead of waiting for a
|
||||
/// potentially very long connection attempt, which would suggest that something is wrong
|
||||
/// anyway, as you are supposed to be connected because of the notification protocol.
|
||||
///
|
||||
/// No limit or throttling of concurrent outbound requests per peer and protocol are enforced.
|
||||
/// Such restrictions, if desired, need to be enforced at the call site(s).
|
||||
///
|
||||
/// The protocol must have been registered through
|
||||
/// `NetworkConfiguration::request_response_protocols`.
|
||||
async fn request(
|
||||
&self,
|
||||
target: PeerId,
|
||||
protocol: Cow<'static, str>,
|
||||
request: Vec<u8>,
|
||||
connect: IfDisconnected,
|
||||
) -> Result<Vec<u8>, RequestFailure>;
|
||||
|
||||
/// Variation of `request` which starts a request whose response is delivered on a provided
|
||||
/// channel.
|
||||
///
|
||||
/// Instead of blocking and waiting for a reply, this function returns immediately, sending
|
||||
/// responses via the passed in sender. This alternative API exists to make it easier to
|
||||
/// integrate with message passing APIs.
|
||||
///
|
||||
/// Keep in mind that the connected receiver might receive a `Canceled` event in case of a
|
||||
/// closing connection. This is expected behaviour. With `request` you would get a
|
||||
/// `RequestFailure::Network(OutboundFailure::ConnectionClosed)` in that case.
|
||||
fn start_request(
|
||||
&self,
|
||||
target: PeerId,
|
||||
protocol: Cow<'static, str>,
|
||||
request: Vec<u8>,
|
||||
tx: oneshot::Sender<Result<Vec<u8>, RequestFailure>>,
|
||||
connect: IfDisconnected,
|
||||
);
|
||||
}
|
||||
|
||||
// Manual implementation to avoid extra boxing here
|
||||
impl<T> NetworkRequest for Arc<T>
|
||||
where
|
||||
T: ?Sized,
|
||||
T: NetworkRequest,
|
||||
{
|
||||
fn request<'life0, 'async_trait>(
|
||||
&'life0 self,
|
||||
target: PeerId,
|
||||
protocol: Cow<'static, str>,
|
||||
request: Vec<u8>,
|
||||
connect: IfDisconnected,
|
||||
) -> Pin<Box<dyn Future<Output = Result<Vec<u8>, RequestFailure>> + Send + 'async_trait>>
|
||||
where
|
||||
'life0: 'async_trait,
|
||||
Self: 'async_trait,
|
||||
{
|
||||
T::request(self, target, protocol, request, connect)
|
||||
}
|
||||
|
||||
fn start_request(
|
||||
&self,
|
||||
target: PeerId,
|
||||
protocol: Cow<'static, str>,
|
||||
request: Vec<u8>,
|
||||
tx: oneshot::Sender<Result<Vec<u8>, RequestFailure>>,
|
||||
connect: IfDisconnected,
|
||||
) {
|
||||
T::start_request(self, target, protocol, request, tx, connect)
|
||||
}
|
||||
}
|
||||
|
||||
/// Provides ability to propagate transactions over the network.
|
||||
pub trait NetworkTransaction<H> {
|
||||
/// You may call this when new transactions are imported by the transaction pool.
|
||||
///
|
||||
/// All transactions will be fetched from the `TransactionPool` that was passed at
|
||||
/// initialization as part of the configuration and propagated to peers.
|
||||
fn trigger_repropagate(&self);
|
||||
|
||||
/// You must call when new transaction is imported by the transaction pool.
|
||||
///
|
||||
/// This transaction will be fetched from the `TransactionPool` that was passed at
|
||||
/// initialization as part of the configuration and propagated to peers.
|
||||
fn propagate_transaction(&self, hash: H);
|
||||
}
|
||||
|
||||
impl<T, H> NetworkTransaction<H> for Arc<T>
|
||||
where
|
||||
T: ?Sized,
|
||||
T: NetworkTransaction<H>,
|
||||
{
|
||||
fn trigger_repropagate(&self) {
|
||||
T::trigger_repropagate(self)
|
||||
}
|
||||
|
||||
fn propagate_transaction(&self, hash: H) {
|
||||
T::propagate_transaction(self, hash)
|
||||
}
|
||||
}
|
||||
|
||||
/// Provides ability to announce blocks to the network.
|
||||
pub trait NetworkBlock<BlockHash, BlockNumber> {
|
||||
/// Make sure an important block is propagated to peers.
|
||||
///
|
||||
/// In chain-based consensus, we often need to make sure non-best forks are
|
||||
/// at least temporarily synced. This function forces such an announcement.
|
||||
fn announce_block(&self, hash: BlockHash, data: Option<Vec<u8>>);
|
||||
|
||||
/// Inform the network service about new best imported block.
|
||||
fn new_best_block_imported(&self, hash: BlockHash, number: BlockNumber);
|
||||
}
|
||||
|
||||
impl<T, BlockHash, BlockNumber> NetworkBlock<BlockHash, BlockNumber> for Arc<T>
|
||||
where
|
||||
T: ?Sized,
|
||||
T: NetworkBlock<BlockHash, BlockNumber>,
|
||||
{
|
||||
fn announce_block(&self, hash: BlockHash, data: Option<Vec<u8>>) {
|
||||
T::announce_block(self, hash, data)
|
||||
}
|
||||
|
||||
fn new_best_block_imported(&self, hash: BlockHash, number: BlockNumber) {
|
||||
T::new_best_block_imported(self, hash, number)
|
||||
}
|
||||
}
|
||||
+4
-1
@@ -18,7 +18,10 @@
|
||||
//
|
||||
// If you read this, you are very thorough, congratulations.
|
||||
|
||||
use super::*;
|
||||
use libp2p::{
|
||||
identity::{error::SigningError, Keypair, PublicKey},
|
||||
PeerId,
|
||||
};
|
||||
|
||||
/// 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
|
||||
@@ -21,7 +21,7 @@ use crate::{
|
||||
discovery::{DiscoveryBehaviour, DiscoveryConfig, DiscoveryOut},
|
||||
peer_info,
|
||||
protocol::{message::Roles, CustomMessageOutcome, NotificationsSink, Protocol},
|
||||
request_responses, DhtEvent, ObservedRole,
|
||||
request_responses,
|
||||
};
|
||||
|
||||
use bytes::Bytes;
|
||||
@@ -41,7 +41,11 @@ use log::debug;
|
||||
|
||||
use sc_client_api::{BlockBackend, ProofProvider};
|
||||
use sc_consensus::import_queue::{IncomingBlock, Origin};
|
||||
use sc_network_common::{config::ProtocolId, request_responses::ProtocolConfig};
|
||||
use sc_network_common::{
|
||||
config::ProtocolId,
|
||||
protocol::event::{DhtEvent, ObservedRole},
|
||||
request_responses::{IfDisconnected, ProtocolConfig, RequestFailure},
|
||||
};
|
||||
use sc_peerset::PeersetHandle;
|
||||
use sp_blockchain::{HeaderBackend, HeaderMetadata};
|
||||
use sp_consensus::BlockOrigin;
|
||||
@@ -57,9 +61,7 @@ use std::{
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
pub use crate::request_responses::{
|
||||
IfDisconnected, InboundFailure, OutboundFailure, RequestFailure, RequestId, ResponseFailure,
|
||||
};
|
||||
pub use crate::request_responses::{InboundFailure, OutboundFailure, RequestId, ResponseFailure};
|
||||
|
||||
/// General behaviour of the network. Combines all protocols together.
|
||||
#[derive(NetworkBehaviour)]
|
||||
|
||||
@@ -262,22 +262,26 @@ pub mod transactions;
|
||||
|
||||
#[doc(inline)]
|
||||
pub use libp2p::{multiaddr, Multiaddr, PeerId};
|
||||
pub use protocol::{
|
||||
event::{DhtEvent, Event, ObservedRole},
|
||||
PeerInfo,
|
||||
};
|
||||
pub use sc_network_common::sync::{
|
||||
warp::{WarpSyncPhase, WarpSyncProgress},
|
||||
StateDownloadProgress, SyncState,
|
||||
pub use protocol::PeerInfo;
|
||||
pub use sc_network_common::{
|
||||
protocol::event::{DhtEvent, Event, ObservedRole},
|
||||
request_responses::{IfDisconnected, RequestFailure},
|
||||
service::{
|
||||
KademliaKey, NetworkBlock, NetworkDHTProvider, NetworkRequest, NetworkSigner,
|
||||
NetworkStateInfo, NetworkStatus, NetworkStatusProvider, NetworkSyncForkRequest,
|
||||
NetworkTransaction, Signature, SigningError,
|
||||
},
|
||||
sync::{
|
||||
warp::{WarpSyncPhase, WarpSyncProgress},
|
||||
StateDownloadProgress, SyncState,
|
||||
},
|
||||
};
|
||||
pub use service::{
|
||||
DecodingError, IfDisconnected, KademliaKey, Keypair, NetworkService, NetworkWorker,
|
||||
NotificationSender, NotificationSenderReady, OutboundFailure, PublicKey, RequestFailure,
|
||||
Signature, SigningError,
|
||||
DecodingError, Keypair, NetworkService, NetworkWorker, NotificationSender,
|
||||
NotificationSenderReady, OutboundFailure, PublicKey,
|
||||
};
|
||||
|
||||
pub use sc_peerset::ReputationChange;
|
||||
use sp_runtime::traits::{Block as BlockT, NumberFor};
|
||||
|
||||
/// The maximum allowed number of established connections per peer.
|
||||
///
|
||||
@@ -296,35 +300,3 @@ pub trait ExHashT: std::hash::Hash + Eq + std::fmt::Debug + Clone + Send + Sync
|
||||
|
||||
impl<T> ExHashT for T where T: std::hash::Hash + Eq + std::fmt::Debug + Clone + Send + Sync + 'static
|
||||
{}
|
||||
|
||||
/// Trait for providing information about the local network state
|
||||
pub trait NetworkStateInfo {
|
||||
/// Returns the local external addresses.
|
||||
fn external_addresses(&self) -> Vec<Multiaddr>;
|
||||
|
||||
/// Returns the local Peer ID.
|
||||
fn local_peer_id(&self) -> PeerId;
|
||||
}
|
||||
|
||||
/// Overview status of the network.
|
||||
#[derive(Clone)]
|
||||
pub struct NetworkStatus<B: BlockT> {
|
||||
/// Current global sync state.
|
||||
pub sync_state: SyncState,
|
||||
/// Target sync block number.
|
||||
pub best_seen_block: Option<NumberFor<B>>,
|
||||
/// Number of peers participating in syncing.
|
||||
pub num_sync_peers: u32,
|
||||
/// Total number of connected peers
|
||||
pub num_connected_peers: usize,
|
||||
/// Total number of active peers.
|
||||
pub num_active_peers: usize,
|
||||
/// The total number of bytes received.
|
||||
pub total_bytes_inbound: u64,
|
||||
/// The total number of bytes sent.
|
||||
pub total_bytes_outbound: u64,
|
||||
/// State sync in progress.
|
||||
pub state_sync: Option<StateDownloadProgress>,
|
||||
/// Warp sync in progress.
|
||||
pub warp_sync: Option<WarpSyncProgress<B>>,
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
use crate::{
|
||||
config, error,
|
||||
request_responses::RequestFailure,
|
||||
utils::{interval, LruHashSet},
|
||||
};
|
||||
|
||||
@@ -45,6 +44,7 @@ use sc_client_api::{BlockBackend, HeaderBackend, ProofProvider};
|
||||
use sc_consensus::import_queue::{BlockImportError, BlockImportStatus, IncomingBlock, Origin};
|
||||
use sc_network_common::{
|
||||
config::ProtocolId,
|
||||
request_responses::RequestFailure,
|
||||
sync::{
|
||||
message::{
|
||||
BlockAnnounce, BlockAttributes, BlockData, BlockRequest, BlockResponse, BlockState,
|
||||
@@ -76,7 +76,6 @@ use std::{
|
||||
|
||||
mod notifications;
|
||||
|
||||
pub mod event;
|
||||
pub mod message;
|
||||
|
||||
pub use notifications::{NotificationsSink, NotifsHandlerError, Ready};
|
||||
|
||||
@@ -50,7 +50,9 @@ use libp2p::{
|
||||
NetworkBehaviourAction, PollParameters,
|
||||
},
|
||||
};
|
||||
use sc_network_common::request_responses::{IncomingRequest, OutgoingResponse, ProtocolConfig};
|
||||
use sc_network_common::request_responses::{
|
||||
IfDisconnected, IncomingRequest, OutgoingResponse, ProtocolConfig, RequestFailure,
|
||||
};
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
collections::{hash_map::Entry, HashMap},
|
||||
@@ -118,26 +120,6 @@ impl From<(Cow<'static, str>, RequestId)> for ProtocolRequestId {
|
||||
}
|
||||
}
|
||||
|
||||
/// When sending a request, what to do on a disconnected recipient.
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum IfDisconnected {
|
||||
/// Try to connect to the peer.
|
||||
TryConnect,
|
||||
/// Just fail if the destination is not yet connected.
|
||||
ImmediateError,
|
||||
}
|
||||
|
||||
/// Convenience functions for `IfDisconnected`.
|
||||
impl IfDisconnected {
|
||||
/// Shall we connect to a disconnected peer?
|
||||
pub fn should_connect(self) -> bool {
|
||||
match self {
|
||||
Self::TryConnect => true,
|
||||
Self::ImmediateError => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Implementation of `NetworkBehaviour` that provides support for request-response protocols.
|
||||
pub struct RequestResponsesBehaviour {
|
||||
/// The multiple sub-protocols, by name.
|
||||
@@ -787,23 +769,6 @@ pub enum RegisterError {
|
||||
DuplicateProtocol(Cow<'static, str>),
|
||||
}
|
||||
|
||||
/// Error in a request.
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
#[allow(missing_docs)]
|
||||
pub enum RequestFailure {
|
||||
#[error("We are not currently connected to the requested peer.")]
|
||||
NotConnected,
|
||||
#[error("Given protocol hasn't been registered.")]
|
||||
UnknownProtocol,
|
||||
#[error("Remote has closed the substream before answering, thereby signaling that it considers the request as valid, but refused to answer it.")]
|
||||
Refused,
|
||||
#[error("The remote replied, but the local node is no longer interested in the response.")]
|
||||
Obsolete,
|
||||
/// Problem on the network.
|
||||
#[error("Problem on the network: {0}")]
|
||||
Network(OutboundFailure),
|
||||
}
|
||||
|
||||
/// Error when processing a request sent by a remote.
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum ResponseFailure {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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,
|
||||
|
||||
@@ -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()
|
||||
},
|
||||
|
||||
@@ -32,7 +32,7 @@ use crate::{
|
||||
protocol::message,
|
||||
service::NetworkService,
|
||||
utils::{interval, LruHashSet},
|
||||
Event, ExHashT, ObservedRole,
|
||||
ExHashT,
|
||||
};
|
||||
|
||||
use codec::{Decode, Encode};
|
||||
@@ -40,7 +40,11 @@ use futures::{channel::mpsc, prelude::*, stream::FuturesUnordered};
|
||||
use libp2p::{multiaddr, PeerId};
|
||||
use log::{debug, trace, warn};
|
||||
use prometheus_endpoint::{register, Counter, PrometheusError, Registry, U64};
|
||||
use sc_network_common::config::ProtocolId;
|
||||
use sc_network_common::{
|
||||
config::ProtocolId,
|
||||
protocol::event::{Event, ObservedRole},
|
||||
service::{NetworkEventStream, NetworkNotification, NetworkPeers},
|
||||
};
|
||||
use sp_runtime::traits::Block as BlockT;
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
@@ -176,7 +180,7 @@ impl TransactionsHandlerPrototype {
|
||||
transaction_pool: Arc<dyn TransactionPool<H, B>>,
|
||||
metrics_registry: Option<&Registry>,
|
||||
) -> error::Result<(TransactionsHandler<B, H>, TransactionsHandlerController<H>)> {
|
||||
let event_stream = service.event_stream("transactions-handler").boxed();
|
||||
let event_stream = service.event_stream("transactions-handler");
|
||||
let (to_handler, from_controller) = mpsc::unbounded();
|
||||
let gossip_enabled = Arc::new(AtomicBool::new(false));
|
||||
|
||||
|
||||
@@ -45,7 +45,8 @@ use sc_client_api::{
|
||||
};
|
||||
use sc_consensus::{
|
||||
BasicQueue, BlockCheckParams, BlockImport, BlockImportParams, BoxJustificationImport,
|
||||
ForkChoiceStrategy, ImportResult, JustificationImport, LongestChain, Verifier,
|
||||
ForkChoiceStrategy, ImportResult, JustificationImport, JustificationSyncLink, LongestChain,
|
||||
Verifier,
|
||||
};
|
||||
pub use sc_network::config::EmptyTransactionPool;
|
||||
use sc_network::{
|
||||
@@ -56,8 +57,9 @@ use sc_network::{
|
||||
Multiaddr, NetworkService, NetworkWorker,
|
||||
};
|
||||
pub use sc_network_common::config::ProtocolId;
|
||||
use sc_network_common::sync::warp::{
|
||||
AuthorityList, EncodedProof, SetId, VerificationResult, WarpSyncProvider,
|
||||
use sc_network_common::{
|
||||
service::{NetworkBlock, NetworkStateInfo, NetworkSyncForkRequest},
|
||||
sync::warp::{AuthorityList, EncodedProof, SetId, VerificationResult, WarpSyncProvider},
|
||||
};
|
||||
use sc_network_light::light_client_requests::handler::LightClientRequestHandler;
|
||||
use sc_network_sync::{
|
||||
@@ -71,7 +73,7 @@ use sp_blockchain::{
|
||||
};
|
||||
use sp_consensus::{
|
||||
block_validation::{BlockAnnounceValidator, DefaultBlockAnnounceValidator},
|
||||
BlockOrigin, Error as ConsensusError,
|
||||
BlockOrigin, Error as ConsensusError, SyncOracle,
|
||||
};
|
||||
use sp_core::H256;
|
||||
use sp_runtime::{
|
||||
@@ -243,7 +245,7 @@ where
|
||||
{
|
||||
/// Get this peer ID.
|
||||
pub fn id(&self) -> PeerId {
|
||||
*self.network.service().local_peer_id()
|
||||
self.network.service().local_peer_id()
|
||||
}
|
||||
|
||||
/// Returns true if we're major syncing.
|
||||
@@ -797,7 +799,7 @@ where
|
||||
let addrs = connect_to
|
||||
.iter()
|
||||
.map(|v| {
|
||||
let peer_id = *self.peer(*v).network_service().local_peer_id();
|
||||
let peer_id = self.peer(*v).network_service().local_peer_id();
|
||||
let multiaddr = self.peer(*v).listen_addr.clone();
|
||||
MultiaddrWithPeerId { peer_id, multiaddr }
|
||||
})
|
||||
@@ -893,7 +895,7 @@ where
|
||||
self.mut_peers(move |peers| {
|
||||
for peer in peers.iter_mut() {
|
||||
peer.network
|
||||
.add_known_address(*network.service().local_peer_id(), listen_addr.clone());
|
||||
.add_known_address(network.service().local_peer_id(), listen_addr.clone());
|
||||
}
|
||||
|
||||
let imported_blocks_stream = Box::pin(client.import_notification_stream().fuse());
|
||||
|
||||
@@ -29,6 +29,7 @@ threadpool = "1.7"
|
||||
tracing = "0.1.29"
|
||||
sc-client-api = { version = "4.0.0-dev", path = "../api" }
|
||||
sc-network = { version = "0.10.0-dev", path = "../network" }
|
||||
sc-network-common = { version = "0.10.0-dev", path = "../network/common" }
|
||||
sc-utils = { version = "4.0.0-dev", path = "../utils" }
|
||||
sp-api = { version = "4.0.0-dev", path = "../../primitives/api" }
|
||||
sp-core = { version = "6.0.0", path = "../../primitives/core" }
|
||||
|
||||
@@ -325,19 +325,88 @@ impl AsyncApi {
|
||||
mod tests {
|
||||
use super::*;
|
||||
use sc_client_db::offchain::LocalStorage;
|
||||
use sc_network::{NetworkStateInfo, PeerId};
|
||||
use sc_network::{PeerId, ReputationChange};
|
||||
use sc_network_common::service::{NetworkPeers, NetworkStateInfo};
|
||||
use sp_core::offchain::{DbExternalities, Externalities};
|
||||
use std::time::SystemTime;
|
||||
use std::{borrow::Cow, time::SystemTime};
|
||||
|
||||
pub(super) struct TestNetwork();
|
||||
|
||||
impl NetworkProvider for TestNetwork {
|
||||
impl NetworkPeers for TestNetwork {
|
||||
fn set_authorized_peers(&self, _peers: HashSet<PeerId>) {
|
||||
unimplemented!()
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn set_authorized_only(&self, _reserved_only: bool) {
|
||||
unimplemented!()
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn add_known_address(&self, _peer_id: PeerId, _addr: Multiaddr) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn report_peer(&self, _who: PeerId, _cost_benefit: ReputationChange) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn disconnect_peer(&self, _who: PeerId, _protocol: Cow<'static, str>) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn accept_unreserved_peers(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn deny_unreserved_peers(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn add_reserved_peer(&self, _peer: String) -> Result<(), String> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn remove_reserved_peer(&self, _peer_id: PeerId) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn set_reserved_peers(
|
||||
&self,
|
||||
_protocol: Cow<'static, str>,
|
||||
_peers: HashSet<Multiaddr>,
|
||||
) -> Result<(), String> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn add_peers_to_reserved_set(
|
||||
&self,
|
||||
_protocol: Cow<'static, str>,
|
||||
_peers: HashSet<Multiaddr>,
|
||||
) -> Result<(), String> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn remove_peers_from_reserved_set(
|
||||
&self,
|
||||
_protocol: Cow<'static, str>,
|
||||
_peers: Vec<PeerId>,
|
||||
) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn add_to_peers_set(
|
||||
&self,
|
||||
_protocol: Cow<'static, str>,
|
||||
_peers: HashSet<Multiaddr>,
|
||||
) -> Result<(), String> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn remove_from_peers_set(&self, _protocol: Cow<'static, str>, _peers: Vec<PeerId>) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn sync_num_connected(&self) -> usize {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -35,14 +35,14 @@
|
||||
|
||||
#![warn(missing_docs)]
|
||||
|
||||
use std::{collections::HashSet, fmt, marker::PhantomData, sync::Arc};
|
||||
use std::{fmt, marker::PhantomData, sync::Arc};
|
||||
|
||||
use futures::{
|
||||
future::{ready, Future},
|
||||
prelude::*,
|
||||
};
|
||||
use parking_lot::Mutex;
|
||||
use sc_network::{ExHashT, NetworkService, NetworkStateInfo, PeerId};
|
||||
use sc_network_common::service::{NetworkPeers, NetworkStateInfo};
|
||||
use sp_api::{ApiExt, ProvideRuntimeApi};
|
||||
use sp_core::{offchain, traits::SpawnNamed, ExecutionContext};
|
||||
use sp_runtime::{
|
||||
@@ -60,27 +60,9 @@ const LOG_TARGET: &str = "offchain-worker";
|
||||
|
||||
/// NetworkProvider provides [`OffchainWorkers`] with all necessary hooks into the
|
||||
/// underlying Substrate networking.
|
||||
pub trait NetworkProvider: NetworkStateInfo {
|
||||
/// Set the authorized peers.
|
||||
fn set_authorized_peers(&self, peers: HashSet<PeerId>);
|
||||
pub trait NetworkProvider: NetworkStateInfo + NetworkPeers {}
|
||||
|
||||
/// Set the authorized only flag.
|
||||
fn set_authorized_only(&self, reserved_only: bool);
|
||||
}
|
||||
|
||||
impl<B, H> NetworkProvider for NetworkService<B, H>
|
||||
where
|
||||
B: traits::Block + 'static,
|
||||
H: ExHashT,
|
||||
{
|
||||
fn set_authorized_peers(&self, peers: HashSet<PeerId>) {
|
||||
NetworkService::set_authorized_peers(self, peers)
|
||||
}
|
||||
|
||||
fn set_authorized_only(&self, reserved_only: bool) {
|
||||
NetworkService::set_authorized_only(self, reserved_only)
|
||||
}
|
||||
}
|
||||
impl<T> NetworkProvider for T where T: NetworkStateInfo + NetworkPeers {}
|
||||
|
||||
/// Options for [`OffchainWorkers`]
|
||||
pub struct OffchainWorkerOptions {
|
||||
@@ -266,11 +248,11 @@ mod tests {
|
||||
use futures::executor::block_on;
|
||||
use sc_block_builder::BlockBuilderProvider as _;
|
||||
use sc_client_api::Backend as _;
|
||||
use sc_network::{Multiaddr, PeerId};
|
||||
use sc_network::{Multiaddr, PeerId, ReputationChange};
|
||||
use sc_transaction_pool::{BasicPool, FullChainApi};
|
||||
use sc_transaction_pool_api::{InPoolTransaction, TransactionPool};
|
||||
use sp_consensus::BlockOrigin;
|
||||
use std::sync::Arc;
|
||||
use std::{borrow::Cow, collections::HashSet, sync::Arc};
|
||||
use substrate_test_runtime_client::{
|
||||
runtime::Block, ClientBlockImportExt, DefaultTestClientBuilderExt, TestClient,
|
||||
TestClientBuilderExt,
|
||||
@@ -288,13 +270,81 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
impl NetworkProvider for TestNetwork {
|
||||
impl NetworkPeers for TestNetwork {
|
||||
fn set_authorized_peers(&self, _peers: HashSet<PeerId>) {
|
||||
unimplemented!()
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn set_authorized_only(&self, _reserved_only: bool) {
|
||||
unimplemented!()
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn add_known_address(&self, _peer_id: PeerId, _addr: Multiaddr) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn report_peer(&self, _who: PeerId, _cost_benefit: ReputationChange) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn disconnect_peer(&self, _who: PeerId, _protocol: Cow<'static, str>) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn accept_unreserved_peers(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn deny_unreserved_peers(&self) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn add_reserved_peer(&self, _peer: String) -> Result<(), String> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn remove_reserved_peer(&self, _peer_id: PeerId) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn set_reserved_peers(
|
||||
&self,
|
||||
_protocol: Cow<'static, str>,
|
||||
_peers: HashSet<Multiaddr>,
|
||||
) -> Result<(), String> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn add_peers_to_reserved_set(
|
||||
&self,
|
||||
_protocol: Cow<'static, str>,
|
||||
_peers: HashSet<Multiaddr>,
|
||||
) -> Result<(), String> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn remove_peers_from_reserved_set(
|
||||
&self,
|
||||
_protocol: Cow<'static, str>,
|
||||
_peers: Vec<PeerId>,
|
||||
) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn add_to_peers_set(
|
||||
&self,
|
||||
_protocol: Cow<'static, str>,
|
||||
_peers: HashSet<Multiaddr>,
|
||||
) -> Result<(), String> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn remove_from_peers_set(&self, _protocol: Cow<'static, str>, _peers: Vec<PeerId>) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn sync_num_connected(&self) -> usize {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,10 @@ use sc_consensus::import_queue::ImportQueue;
|
||||
use sc_executor::RuntimeVersionOf;
|
||||
use sc_keystore::LocalKeystore;
|
||||
use sc_network::{config::SyncMode, NetworkService};
|
||||
use sc_network_common::sync::warp::WarpSyncProvider;
|
||||
use sc_network_common::{
|
||||
service::{NetworkStateInfo, NetworkStatusProvider, NetworkTransaction},
|
||||
sync::warp::WarpSyncProvider,
|
||||
};
|
||||
use sc_network_light::light_client_requests::handler::LightClientRequestHandler;
|
||||
use sc_network_sync::{
|
||||
block_request_handler::BlockRequestHandler, state_request_handler::StateRequestHandler,
|
||||
@@ -319,6 +322,31 @@ where
|
||||
)
|
||||
}
|
||||
|
||||
/// Shared network instance implementing a set of mandatory traits.
|
||||
pub trait SpawnTaskNetwork<Block: BlockT>:
|
||||
sc_offchain::NetworkProvider
|
||||
+ NetworkStateInfo
|
||||
+ NetworkTransaction<Block::Hash>
|
||||
+ NetworkStatusProvider<Block>
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static
|
||||
{
|
||||
}
|
||||
|
||||
impl<T, Block> SpawnTaskNetwork<Block> for T
|
||||
where
|
||||
Block: BlockT,
|
||||
T: sc_offchain::NetworkProvider
|
||||
+ NetworkStateInfo
|
||||
+ NetworkTransaction<Block::Hash>
|
||||
+ NetworkStatusProvider<Block>
|
||||
+ Send
|
||||
+ Sync
|
||||
+ 'static,
|
||||
{
|
||||
}
|
||||
|
||||
/// Parameters to pass into `build`.
|
||||
pub struct SpawnTasksParams<'a, TBl: BlockT, TCl, TExPool, TRpc, Backend> {
|
||||
/// The service configuration.
|
||||
@@ -337,7 +365,7 @@ pub struct SpawnTasksParams<'a, TBl: BlockT, TCl, TExPool, TRpc, Backend> {
|
||||
pub rpc_builder:
|
||||
Box<dyn Fn(DenyUnsafe, SubscriptionTaskExecutor) -> Result<RpcModule<TRpc>, Error>>,
|
||||
/// A shared network instance.
|
||||
pub network: Arc<NetworkService<TBl, <TBl as BlockT>::Hash>>,
|
||||
pub network: Arc<dyn SpawnTaskNetwork<TBl>>,
|
||||
/// A Sender for RPC requests.
|
||||
pub system_rpc_tx: TracingUnboundedSender<sc_rpc::system::Request<TBl>>,
|
||||
/// Telemetry instance for this node.
|
||||
@@ -349,7 +377,7 @@ pub fn build_offchain_workers<TBl, TCl>(
|
||||
config: &Configuration,
|
||||
spawn_handle: SpawnTaskHandle,
|
||||
client: Arc<TCl>,
|
||||
network: Arc<NetworkService<TBl, <TBl as BlockT>::Hash>>,
|
||||
network: Arc<dyn sc_offchain::NetworkProvider + Send + Sync>,
|
||||
) -> Option<Arc<sc_offchain::OffchainWorkers<TCl, TBl>>>
|
||||
where
|
||||
TBl: BlockT,
|
||||
@@ -516,13 +544,14 @@ where
|
||||
Ok(rpc_handlers)
|
||||
}
|
||||
|
||||
async fn transaction_notifications<TBl, TExPool>(
|
||||
transaction_pool: Arc<TExPool>,
|
||||
network: Arc<NetworkService<TBl, <TBl as BlockT>::Hash>>,
|
||||
async fn transaction_notifications<Block, ExPool, Network>(
|
||||
transaction_pool: Arc<ExPool>,
|
||||
network: Network,
|
||||
telemetry: Option<TelemetryHandle>,
|
||||
) where
|
||||
TBl: BlockT,
|
||||
TExPool: MaintainedTransactionPool<Block = TBl, Hash = <TBl as BlockT>::Hash>,
|
||||
Block: BlockT,
|
||||
ExPool: MaintainedTransactionPool<Block = Block, Hash = <Block as BlockT>::Hash>,
|
||||
Network: NetworkTransaction<<Block as BlockT>::Hash> + Send + Sync,
|
||||
{
|
||||
// transaction notifications
|
||||
transaction_pool
|
||||
@@ -542,13 +571,18 @@ async fn transaction_notifications<TBl, TExPool>(
|
||||
.await;
|
||||
}
|
||||
|
||||
fn init_telemetry<TBl: BlockT, TCl: BlockBackend<TBl>>(
|
||||
fn init_telemetry<Block, Client, Network>(
|
||||
config: &mut Configuration,
|
||||
network: Arc<NetworkService<TBl, <TBl as BlockT>::Hash>>,
|
||||
client: Arc<TCl>,
|
||||
network: Network,
|
||||
client: Arc<Client>,
|
||||
telemetry: &mut Telemetry,
|
||||
sysinfo: Option<sc_telemetry::SysInfo>,
|
||||
) -> sc_telemetry::Result<TelemetryHandle> {
|
||||
) -> sc_telemetry::Result<TelemetryHandle>
|
||||
where
|
||||
Block: BlockT,
|
||||
Client: BlockBackend<Block>,
|
||||
Network: NetworkStateInfo,
|
||||
{
|
||||
let genesis_hash = client.block_hash(Zero::zero()).ok().flatten().unwrap_or_default();
|
||||
let connection_message = ConnectionMessage {
|
||||
name: config.network.node_name.to_owned(),
|
||||
|
||||
@@ -42,9 +42,11 @@ use jsonrpsee::{core::Error as JsonRpseeError, RpcModule};
|
||||
use log::{debug, error, warn};
|
||||
use sc_client_api::{blockchain::HeaderBackend, BlockBackend, BlockchainEvents, ProofProvider};
|
||||
use sc_network::PeerId;
|
||||
use sc_network_common::service::NetworkBlock;
|
||||
use sc_rpc_server::WsConfig;
|
||||
use sc_utils::mpsc::TracingUnboundedReceiver;
|
||||
use sp_blockchain::HeaderMetadata;
|
||||
use sp_consensus::SyncOracle;
|
||||
use sp_runtime::{
|
||||
generic::BlockId,
|
||||
traits::{Block as BlockT, Header as HeaderT},
|
||||
|
||||
@@ -22,7 +22,8 @@ use crate::config::Configuration;
|
||||
use futures_timer::Delay;
|
||||
use prometheus_endpoint::{register, Gauge, GaugeVec, Opts, PrometheusError, Registry, U64};
|
||||
use sc_client_api::{ClientInfo, UsageProvider};
|
||||
use sc_network::{config::Role, NetworkService, NetworkStatus};
|
||||
use sc_network::config::Role;
|
||||
use sc_network_common::service::{NetworkStatus, NetworkStatusProvider};
|
||||
use sc_telemetry::{telemetry, TelemetryHandle, SUBSTRATE_INFO};
|
||||
use sc_transaction_pool_api::{MaintainedTransactionPool, PoolStatus};
|
||||
use sc_utils::metrics::register_globals;
|
||||
@@ -182,15 +183,16 @@ impl MetricsService {
|
||||
/// Returns a never-ending `Future` that performs the
|
||||
/// metric and telemetry updates with information from
|
||||
/// the given sources.
|
||||
pub async fn run<TBl, TExPool, TCl>(
|
||||
pub async fn run<TBl, TExPool, TCl, TNet>(
|
||||
mut self,
|
||||
client: Arc<TCl>,
|
||||
transactions: Arc<TExPool>,
|
||||
network: Arc<NetworkService<TBl, <TBl as Block>::Hash>>,
|
||||
network: TNet,
|
||||
) where
|
||||
TBl: Block,
|
||||
TCl: ProvideRuntimeApi<TBl> + UsageProvider<TBl>,
|
||||
TExPool: MaintainedTransactionPool<Block = TBl, Hash = <TBl as Block>::Hash>,
|
||||
TNet: NetworkStatusProvider<TBl>,
|
||||
{
|
||||
let mut timer = Delay::new(Duration::from_secs(0));
|
||||
let timer_interval = Duration::from_secs(5);
|
||||
|
||||
@@ -27,6 +27,7 @@ sc-client-db = { version = "0.10.0-dev", default-features = false, path = "../..
|
||||
sc-consensus = { version = "0.10.0-dev", path = "../../../client/consensus/common" }
|
||||
sc-executor = { version = "0.10.0-dev", path = "../../executor" }
|
||||
sc-network = { version = "0.10.0-dev", path = "../../network" }
|
||||
sc-network-common = { version = "0.10.0-dev", path = "../../network/common" }
|
||||
sc-service = { version = "0.10.0-dev", features = ["test-helpers"], path = "../../service" }
|
||||
sc-transaction-pool-api = { version = "4.0.0-dev", path = "../../../client/transaction-pool/api" }
|
||||
sp-api = { version = "4.0.0-dev", path = "../../../primitives/api" }
|
||||
|
||||
@@ -26,6 +26,7 @@ use sc_network::{
|
||||
config::{NetworkConfiguration, TransportConfig},
|
||||
multiaddr, Multiaddr,
|
||||
};
|
||||
use sc_network_common::service::{NetworkBlock, NetworkPeers, NetworkStateInfo};
|
||||
use sc_service::{
|
||||
client::Client,
|
||||
config::{BasePath, DatabaseSource, KeystoreConfig},
|
||||
@@ -320,7 +321,7 @@ where
|
||||
|
||||
handle.spawn(service.clone().map_err(|_| ()));
|
||||
let addr =
|
||||
addr.with(multiaddr::Protocol::P2p((*service.network().local_peer_id()).into()));
|
||||
addr.with(multiaddr::Protocol::P2p((service.network().local_peer_id()).into()));
|
||||
self.authority_nodes.push((self.nodes, service, user_data, addr));
|
||||
self.nodes += 1;
|
||||
}
|
||||
@@ -340,7 +341,7 @@ where
|
||||
|
||||
handle.spawn(service.clone().map_err(|_| ()));
|
||||
let addr =
|
||||
addr.with(multiaddr::Protocol::P2p((*service.network().local_peer_id()).into()));
|
||||
addr.with(multiaddr::Protocol::P2p((service.network().local_peer_id()).into()));
|
||||
self.full_nodes.push((self.nodes, service, user_data, addr));
|
||||
self.nodes += 1;
|
||||
}
|
||||
@@ -387,7 +388,7 @@ where
|
||||
}
|
||||
|
||||
network.run_until_all_full(move |_index, service| {
|
||||
let connected = service.network().num_connected();
|
||||
let connected = service.network().sync_num_connected();
|
||||
debug!("Got {}/{} full connections...", connected, expected_full_connections);
|
||||
connected == expected_full_connections
|
||||
});
|
||||
@@ -422,7 +423,7 @@ where
|
||||
}
|
||||
|
||||
network.run_until_all_full(move |_index, service| {
|
||||
let connected = service.network().num_connected();
|
||||
let connected = service.network().sync_num_connected();
|
||||
debug!("Got {}/{} full connections...", connected, expected_full_connections);
|
||||
connected == expected_full_connections
|
||||
});
|
||||
|
||||
@@ -236,10 +236,10 @@ pub trait Proposer<B: BlockT> {
|
||||
pub trait SyncOracle {
|
||||
/// Whether the synchronization service is undergoing major sync.
|
||||
/// Returns true if so.
|
||||
fn is_major_syncing(&mut self) -> bool;
|
||||
fn is_major_syncing(&self) -> bool;
|
||||
/// Whether the synchronization service is offline.
|
||||
/// Returns true if so.
|
||||
fn is_offline(&mut self) -> bool;
|
||||
fn is_offline(&self) -> bool;
|
||||
}
|
||||
|
||||
/// A synchronization oracle for when there is no network.
|
||||
@@ -247,10 +247,10 @@ pub trait SyncOracle {
|
||||
pub struct NoNetwork;
|
||||
|
||||
impl SyncOracle for NoNetwork {
|
||||
fn is_major_syncing(&mut self) -> bool {
|
||||
fn is_major_syncing(&self) -> bool {
|
||||
false
|
||||
}
|
||||
fn is_offline(&mut self) -> bool {
|
||||
fn is_offline(&self) -> bool {
|
||||
false
|
||||
}
|
||||
}
|
||||
@@ -258,14 +258,14 @@ impl SyncOracle for NoNetwork {
|
||||
impl<T> SyncOracle for Arc<T>
|
||||
where
|
||||
T: ?Sized,
|
||||
for<'r> &'r T: SyncOracle,
|
||||
T: SyncOracle,
|
||||
{
|
||||
fn is_major_syncing(&mut self) -> bool {
|
||||
<&T>::is_major_syncing(&mut &**self)
|
||||
fn is_major_syncing(&self) -> bool {
|
||||
T::is_major_syncing(self)
|
||||
}
|
||||
|
||||
fn is_offline(&mut self) -> bool {
|
||||
<&T>::is_offline(&mut &**self)
|
||||
fn is_offline(&self) -> bool {
|
||||
T::is_offline(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user