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

Commit

Permalink
Move block announcement protocol config out of Protocol (#12441)
Browse files Browse the repository at this point in the history
* Move Role(s) to `sc-network-common`

* Introduce `NotificationHandshake` type

* Move block announce protocol config creation to `ChainSync`

* Include block announcement into `notification_protocols`

* Apply review comments

* Remove unneeded include

* Add missing include

* Apply review comments
  • Loading branch information
altonen authored Oct 10, 2022
1 parent 73c4f94 commit 0c1ccda
Show file tree
Hide file tree
Showing 23 changed files with 439 additions and 263 deletions.
2 changes: 1 addition & 1 deletion client/finality-grandpa/src/communication/gossip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ use parity_scale_codec::{Decode, Encode};
use prometheus_endpoint::{register, CounterVec, Opts, PrometheusError, Registry, U64};
use rand::seq::SliceRandom;
use sc_network::{PeerId, ReputationChange};
use sc_network_common::protocol::event::ObservedRole;
use sc_network_common::protocol::role::ObservedRole;
use sc_network_gossip::{MessageIntent, ValidatorContext};
use sc_telemetry::{telemetry, TelemetryHandle, CONSENSUS_DEBUG};
use sc_utils::mpsc::{tracing_unbounded, TracingUnboundedReceiver, TracingUnboundedSender};
Expand Down
5 changes: 1 addition & 4 deletions client/finality-grandpa/src/communication/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,7 @@ use parity_scale_codec::Encode;
use sc_network::{config::Role, Multiaddr, PeerId, ReputationChange};
use sc_network_common::{
config::MultiaddrWithPeerId,
protocol::{
event::{Event as NetworkEvent, ObservedRole},
ProtocolName,
},
protocol::{event::Event as NetworkEvent, role::ObservedRole, ProtocolName},
service::{
NetworkBlock, NetworkEventStream, NetworkNotification, NetworkPeers,
NetworkSyncForkRequest, NotificationSender, NotificationSenderError,
Expand Down
1 change: 1 addition & 0 deletions client/finality-grandpa/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,7 @@ pub fn grandpa_peers_set_config(
fallback_names: grandpa_protocol_name::LEGACY_NAMES.iter().map(|&n| n.into()).collect(),
// Notifications reach ~256kiB in size at the time of writing on Kusama and Polkadot.
max_notification_size: 1024 * 1024,
handshake: None,
set_config: sc_network_common::config::SetConfig {
in_peers: 0,
out_peers: 0,
Expand Down
2 changes: 1 addition & 1 deletion client/network-gossip/src/bridge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ mod tests {
use quickcheck::{Arbitrary, Gen, QuickCheck};
use sc_network_common::{
config::MultiaddrWithPeerId,
protocol::event::ObservedRole,
protocol::role::ObservedRole,
service::{
NetworkBlock, NetworkEventStream, NetworkNotification, NetworkPeers,
NotificationSender, NotificationSenderError,
Expand Down
2 changes: 1 addition & 1 deletion client/network-gossip/src/state_machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use ahash::AHashSet;
use libp2p::PeerId;
use lru::LruCache;
use prometheus_endpoint::{register, Counter, PrometheusError, Registry, U64};
use sc_network_common::protocol::{event::ObservedRole, ProtocolName};
use sc_network_common::protocol::{role::ObservedRole, ProtocolName};
use sp_runtime::traits::{Block as BlockT, Hash, HashFor};
use std::{collections::HashMap, iter, sync::Arc, time, time::Instant};

Expand Down
2 changes: 1 addition & 1 deletion client/network-gossip/src/validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.

use libp2p::PeerId;
use sc_network_common::protocol::event::ObservedRole;
use sc_network_common::protocol::role::ObservedRole;
use sp_runtime::traits::Block as BlockT;

/// Validates consensus messages.
Expand Down
2 changes: 1 addition & 1 deletion client/network/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ sp-runtime = { version = "6.0.0", path = "../../primitives/runtime" }

[dev-dependencies]
assert_matches = "1.3"
async-std = "1.11.0"
async-std = { version = "1.11.0", features = ["attributes"] }
rand = "0.7.2"
tempfile = "3.1.0"
sc-network-light = { version = "0.10.0-dev", path = "./light" }
Expand Down
28 changes: 28 additions & 0 deletions client/network/common/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use crate::protocol;

use codec::Encode;
use libp2p::{multiaddr, Multiaddr, PeerId};
use std::{fmt, str, str::FromStr};

Expand Down Expand Up @@ -199,6 +200,30 @@ impl Default for SetConfig {
}
}

/// Custom handshake for the notification protocol
#[derive(Debug, Clone)]
pub struct NotificationHandshake(Vec<u8>);

impl NotificationHandshake {
/// Create new `NotificationHandshake` from an object that implements `Encode`
pub fn new<H: Encode>(handshake: H) -> Self {
Self(handshake.encode())
}

/// Create new `NotificationHandshake` from raw bytes
pub fn from_bytes(bytes: Vec<u8>) -> Self {
Self(bytes)
}
}

impl std::ops::Deref for NotificationHandshake {
type Target = Vec<u8>;

fn deref(&self) -> &Self::Target {
&self.0
}
}

/// Extension to [`SetConfig`] for sets that aren't the default set.
///
/// > **Note**: As new fields might be added in the future, please consider using the `new` method
Expand All @@ -218,6 +243,8 @@ pub struct NonDefaultSetConfig {
/// If a fallback is used, it will be reported in
/// `sc_network::protocol::event::Event::NotificationStreamOpened::negotiated_fallback`
pub fallback_names: Vec<protocol::ProtocolName>,
/// Handshake of the protocol
pub handshake: Option<NotificationHandshake>,
/// Maximum allowed size of single notifications.
pub max_notification_size: u64,
/// Base configuration.
Expand All @@ -231,6 +258,7 @@ impl NonDefaultSetConfig {
notifications_protocol,
max_notification_size,
fallback_names: Vec::new(),
handshake: None,
set_config: SetConfig {
in_peers: 0,
out_peers: 0,
Expand Down
1 change: 1 addition & 0 deletions client/network/common/src/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use std::{
use libp2p::core::upgrade;

pub mod event;
pub mod role;

/// The protocol name transmitted on the wire.
#[derive(Debug, Clone)]
Expand Down
24 changes: 1 addition & 23 deletions client/network/common/src/protocol/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
//! events that happen on the network like DHT get/put results received.
use super::ProtocolName;
use crate::protocol::role::ObservedRole;
use bytes::Bytes;
use libp2p::{core::PeerId, kad::record::Key};

Expand Down Expand Up @@ -97,26 +98,3 @@ pub enum Event {
messages: Vec<(ProtocolName, Bytes)>,
},
}

/// Role that the peer sent to us during the handshake, with the addition of what our local node
/// knows about that peer.
///
/// > **Note**: This enum is different from the `Role` enum. The `Role` enum indicates what a
/// > node says about itself, while `ObservedRole` is a `Role` merged with the
/// > information known locally about that node.
#[derive(Debug, Clone)]
pub enum ObservedRole {
/// Full node.
Full,
/// Light node.
Light,
/// Third-party authority.
Authority,
}

impl ObservedRole {
/// Returns `true` for `ObservedRole::Light`.
pub fn is_light(&self) -> bool {
matches!(self, Self::Light)
}
}
121 changes: 121 additions & 0 deletions client/network/common/src/protocol/role.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
// This file is part of Substrate.

// Copyright (C) 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/>.

use codec::{self, Encode, EncodeLike, Input, Output};

/// Role that the peer sent to us during the handshake, with the addition of what our local node
/// knows about that peer.
///
/// > **Note**: This enum is different from the `Role` enum. The `Role` enum indicates what a
/// > node says about itself, while `ObservedRole` is a `Role` merged with the
/// > information known locally about that node.
#[derive(Debug, Clone)]
pub enum ObservedRole {
/// Full node.
Full,
/// Light node.
Light,
/// Third-party authority.
Authority,
}

impl ObservedRole {
/// Returns `true` for `ObservedRole::Light`.
pub fn is_light(&self) -> bool {
matches!(self, Self::Light)
}
}

/// Role of the local node.
#[derive(Debug, Clone)]
pub enum Role {
/// Regular full node.
Full,
/// Actual authority.
Authority,
}

impl Role {
/// True for [`Role::Authority`].
pub fn is_authority(&self) -> bool {
matches!(self, Self::Authority)
}
}

impl std::fmt::Display for Role {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Full => write!(f, "FULL"),
Self::Authority => write!(f, "AUTHORITY"),
}
}
}

bitflags::bitflags! {
/// Bitmask of the roles that a node fulfills.
pub struct Roles: u8 {
/// No network.
const NONE = 0b00000000;
/// Full node, does not participate in consensus.
const FULL = 0b00000001;
/// Light client node.
const LIGHT = 0b00000010;
/// Act as an authority
const AUTHORITY = 0b00000100;
}
}

impl Roles {
/// Does this role represents a client that holds full chain data locally?
pub fn is_full(&self) -> bool {
self.intersects(Self::FULL | Self::AUTHORITY)
}

/// Does this role represents a client that does not participates in the consensus?
pub fn is_authority(&self) -> bool {
*self == Self::AUTHORITY
}

/// Does this role represents a client that does not hold full chain data locally?
pub fn is_light(&self) -> bool {
!self.is_full()
}
}

impl<'a> From<&'a Role> for Roles {
fn from(roles: &'a Role) -> Self {
match roles {
Role::Full => Self::FULL,
Role::Authority => Self::AUTHORITY,
}
}
}

impl Encode for Roles {
fn encode_to<T: Output + ?Sized>(&self, dest: &mut T) {
dest.push_byte(self.bits())
}
}

impl EncodeLike for Roles {}

impl codec::Decode for Roles {
fn decode<I: Input>(input: &mut I) -> Result<Self, codec::Error> {
Self::from_bits(input.read_byte()?).ok_or_else(|| codec::Error::from("Invalid bytes"))
}
}
28 changes: 27 additions & 1 deletion client/network/common/src/sync/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,12 @@
//! Network packet message types. These get serialized and put into the lower level protocol
//! payload.
use crate::protocol::role::Roles;

use bitflags::bitflags;
use codec::{Decode, Encode, Error, Input, Output};
pub use generic::{BlockAnnounce, FromBlock};
use sp_runtime::traits::{Block as BlockT, Header as HeaderT};
use sp_runtime::traits::{Block as BlockT, Header as HeaderT, NumberFor};

/// Type alias for using the block request type using block type parameters.
pub type BlockRequest<B> =
Expand Down Expand Up @@ -218,3 +220,27 @@ pub mod generic {
}
}
}

/// Handshake sent when we open a block announces substream.
#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
pub struct BlockAnnouncesHandshake<B: BlockT> {
/// Roles of the node.
pub roles: Roles,
/// Best block number.
pub best_number: NumberFor<B>,
/// Best block hash.
pub best_hash: B::Hash,
/// Genesis block hash.
pub genesis_hash: B::Hash,
}

impl<B: BlockT> BlockAnnouncesHandshake<B> {
pub fn build(
roles: Roles,
best_number: NumberFor<B>,
best_hash: B::Hash,
genesis_hash: B::Hash,
) -> Self {
Self { genesis_hash, roles, best_number, best_hash }
}
}
5 changes: 3 additions & 2 deletions client/network/src/behaviour.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
use crate::{
discovery::{DiscoveryBehaviour, DiscoveryConfig, DiscoveryOut},
peer_info,
protocol::{message::Roles, CustomMessageOutcome, NotificationsSink, Protocol},
protocol::{CustomMessageOutcome, NotificationsSink, Protocol},
request_responses,
};

Expand All @@ -41,7 +41,8 @@ use sc_consensus::import_queue::{IncomingBlock, RuntimeOrigin};
use sc_network_common::{
config::ProtocolId,
protocol::{
event::{DhtEvent, ObservedRole},
event::DhtEvent,
role::{ObservedRole, Roles},
ProtocolName,
},
request_responses::{IfDisconnected, ProtocolConfig, RequestFailure},
Expand Down
29 changes: 4 additions & 25 deletions client/network/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
pub use sc_network_common::{
config::ProtocolId,
protocol::role::Role,
request_responses::{
IncomingRequest, OutgoingResponse, ProtocolConfig as RequestResponseConfig,
},
Expand Down Expand Up @@ -93,6 +94,9 @@ where
/// Registry for recording prometheus metrics to.
pub metrics_registry: Option<Registry>,

/// Block announce protocol configuration
pub block_announce_config: NonDefaultSetConfig,

/// Request response configuration for the block request protocol.
///
/// [`RequestResponseConfig::name`] is used to tag outgoing block requests with the correct
Expand Down Expand Up @@ -130,31 +134,6 @@ where
pub request_response_protocol_configs: Vec<RequestResponseConfig>,
}

/// Role of the local node.
#[derive(Debug, Clone)]
pub enum Role {
/// Regular full node.
Full,
/// Actual authority.
Authority,
}

impl Role {
/// True for [`Role::Authority`].
pub fn is_authority(&self) -> bool {
matches!(self, Self::Authority { .. })
}
}

impl fmt::Display for Role {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Full => write!(f, "FULL"),
Self::Authority { .. } => write!(f, "AUTHORITY"),
}
}
}

/// Sync operation mode.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum SyncMode {
Expand Down
Loading

0 comments on commit 0c1ccda

Please sign in to comment.