Split the Roles in three types (#5520)

* Split the Roles bitfield in three

* Forgot to include some changes

* Fix cli test

* More test fixes

* Oh God, merging master broke other tests

* Didn't run the doctests

* Address review

* I'm trying to fix the build blindly because it's taking a good hour to compile on my machine

* Address some review

* Also update the peerset's API to make sense

* Fix peerset tests

* Fix browser node

* client: distinguish between local and network authority

Co-authored-by: André Silva <andre.beat@gmail.com>
This commit is contained in:
Pierre Krieger
2020-04-03 19:08:14 +02:00
committed by GitHub
parent 9dbcb11f66
commit 8c03a4fcef
44 changed files with 591 additions and 432 deletions
+25 -3
View File
@@ -17,7 +17,6 @@
//! Network event types. These are are not the part of the protocol, but rather
//! events that happen on the network like DHT get/put results received.
use crate::config::Roles;
use bytes::Bytes;
use libp2p::core::PeerId;
use libp2p::kad::record::Key;
@@ -55,8 +54,8 @@ pub enum Event {
remote: PeerId,
/// The concerned protocol. Each protocol uses a different substream.
engine_id: ConsensusEngineId,
/// Roles that the remote .
roles: Roles,
/// Role of the remote.
role: ObservedRole,
},
/// Closed a substream with the given node. Always matches a corresponding previous
@@ -76,3 +75,26 @@ pub enum Event {
messages: Vec<(ConsensusEngineId, Bytes)>,
},
}
/// Role that the peer sent to us during the handshake, with the addition of what our local node
/// knows about that peer.
#[derive(Debug, Clone)]
pub enum ObservedRole {
/// Full node.
Full,
/// Light node.
Light,
/// When we are a validator node, this is a sentry that protects us.
OurSentry,
/// When we are a sentry node, this is the authority we are protecting.
OurGuardedAuthority,
/// Third-party authority.
Authority,
}
impl ObservedRole {
/// Returns `true` for `ObservedRole::Light`.
pub fn is_light(&self) -> bool {
matches!(self, ObservedRole::Light)
}
}
@@ -78,7 +78,7 @@ fn build_nodes() -> (Swarm<CustomProtoWithAddr>, Swarm<CustomProtoWithAddr>) {
vec![]
},
reserved_only: false,
reserved_nodes: Vec::new(),
priority_groups: Vec::new(),
});
let behaviour = CustomProtoWithAddr {
@@ -1423,7 +1423,7 @@ mod tests {
out_peers: 128,
bootnodes: Vec::new(),
reserved_only: false,
reserved_nodes: Vec::new(),
priority_groups: Vec::new(),
};
sc_peerset::Peerset::from_config(cfg)
}
@@ -24,7 +24,7 @@ pub use self::generic::{
RemoteHeaderRequest, RemoteHeaderResponse,
RemoteChangesRequest, RemoteChangesResponse,
FinalityProofRequest, FinalityProofResponse,
FromBlock, RemoteReadChildRequest,
FromBlock, RemoteReadChildRequest, Roles,
};
use sc_client_api::StorageProof;
@@ -137,14 +137,71 @@ pub struct RemoteReadResponse {
/// Generic types.
pub mod generic {
use bitflags::bitflags;
use codec::{Encode, Decode, Input, Output};
use sp_runtime::Justification;
use crate::config::Roles;
use super::{
RemoteReadResponse, Transactions, Direction,
RequestId, BlockAttributes, RemoteCallResponse, ConsensusEngineId,
BlockState, StorageProof,
};
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(Roles::FULL | Roles::AUTHORITY)
}
/// Does this role represents a client that does not participates in the consensus?
pub fn is_authority(&self) -> bool {
*self == Roles::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 crate::config::Role> for Roles {
fn from(roles: &'a crate::config::Role) -> Self {
match roles {
crate::config::Role::Full => Roles::FULL,
crate::config::Role::Light => Roles::LIGHT,
crate::config::Role::Sentry { .. } => Roles::AUTHORITY,
crate::config::Role::Authority { .. } => Roles::AUTHORITY,
}
}
}
impl codec::Encode for Roles {
fn encode_to<T: codec::Output>(&self, dest: &mut T) {
dest.push_byte(self.bits())
}
}
impl codec::EncodeLike for Roles {}
impl codec::Decode for Roles {
fn decode<I: codec::Input>(input: &mut I) -> Result<Self, codec::Error> {
Self::from_bits(input.read_byte()?).ok_or_else(|| codec::Error::from("Invalid bytes"))
}
}
/// Consensus is mostly opaque to us
#[derive(Debug, PartialEq, Eq, Clone, Encode, Decode)]
pub struct ConsensusMessage {
@@ -34,9 +34,9 @@ use sp_consensus::{BlockOrigin, BlockStatus,
import_queue::{IncomingBlock, BlockImportResult, BlockImportError}
};
use crate::{
config::{Roles, BoxFinalityProofRequestBuilder},
config::BoxFinalityProofRequestBuilder,
protocol::message::{self, generic::FinalityProofRequest, BlockAnnounce, BlockAttributes, BlockRequest, BlockResponse,
FinalityProofResponse},
FinalityProofResponse, Roles},
};
use either::Either;
use extra_requests::ExtraRequests;