mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-15 11:31:05 +00:00
Remove necessity to pass ConsensusEngineId when registering notifications protocol (#7549)
* Remove necessity to pass ConsensusEngineId when registering notifications protocol * Line width * Fix tests protocol name * Other renames * Doc update * Change issue in TODO
This commit is contained in:
@@ -23,7 +23,7 @@ use futures::prelude::*;
|
||||
use futures::channel::mpsc::{channel, Sender, Receiver};
|
||||
use libp2p::PeerId;
|
||||
use log::trace;
|
||||
use sp_runtime::{traits::Block as BlockT, ConsensusEngineId};
|
||||
use sp_runtime::traits::Block as BlockT;
|
||||
use std::{
|
||||
borrow::Cow,
|
||||
collections::{HashMap, VecDeque},
|
||||
@@ -38,7 +38,7 @@ pub struct GossipEngine<B: BlockT> {
|
||||
state_machine: ConsensusGossip<B>,
|
||||
network: Box<dyn Network<B> + Send>,
|
||||
periodic_maintenance_interval: futures_timer::Delay,
|
||||
engine_id: ConsensusEngineId,
|
||||
protocol: Cow<'static, str>,
|
||||
|
||||
/// Incoming events from the network.
|
||||
network_event_stream: Pin<Box<dyn Stream<Item = Event> + Send>>,
|
||||
@@ -68,20 +68,21 @@ impl<B: BlockT> GossipEngine<B> {
|
||||
/// Create a new instance.
|
||||
pub fn new<N: Network<B> + Send + Clone + 'static>(
|
||||
network: N,
|
||||
engine_id: ConsensusEngineId,
|
||||
protocol_name: impl Into<Cow<'static, str>>,
|
||||
protocol: impl Into<Cow<'static, str>>,
|
||||
validator: Arc<dyn Validator<B>>,
|
||||
) -> Self where B: 'static {
|
||||
let protocol = protocol.into();
|
||||
|
||||
// We grab the event stream before registering the notifications protocol, otherwise we
|
||||
// might miss events.
|
||||
let network_event_stream = network.event_stream();
|
||||
network.register_notifications_protocol(engine_id, protocol_name.into());
|
||||
network.register_notifications_protocol(protocol.clone());
|
||||
|
||||
GossipEngine {
|
||||
state_machine: ConsensusGossip::new(validator, engine_id),
|
||||
state_machine: ConsensusGossip::new(validator, protocol.clone()),
|
||||
network: Box::new(network),
|
||||
periodic_maintenance_interval: futures_timer::Delay::new(PERIODIC_MAINTENANCE_INTERVAL),
|
||||
engine_id,
|
||||
protocol,
|
||||
|
||||
network_event_stream,
|
||||
message_sinks: HashMap::new(),
|
||||
@@ -181,21 +182,21 @@ impl<B: BlockT> Future for GossipEngine<B> {
|
||||
ForwardingState::Idle => {
|
||||
match this.network_event_stream.poll_next_unpin(cx) {
|
||||
Poll::Ready(Some(event)) => match event {
|
||||
Event::NotificationStreamOpened { remote, engine_id, role } => {
|
||||
if engine_id != this.engine_id {
|
||||
Event::NotificationStreamOpened { remote, protocol, role } => {
|
||||
if protocol != this.protocol {
|
||||
continue;
|
||||
}
|
||||
this.state_machine.new_peer(&mut *this.network, remote, role);
|
||||
}
|
||||
Event::NotificationStreamClosed { remote, engine_id } => {
|
||||
if engine_id != this.engine_id {
|
||||
Event::NotificationStreamClosed { remote, protocol } => {
|
||||
if protocol != this.protocol {
|
||||
continue;
|
||||
}
|
||||
this.state_machine.peer_disconnected(&mut *this.network, remote);
|
||||
},
|
||||
Event::NotificationsReceived { remote, messages } => {
|
||||
let messages = messages.into_iter().filter_map(|(engine, data)| {
|
||||
if engine == this.engine_id {
|
||||
if engine == this.protocol {
|
||||
Some(data.to_vec())
|
||||
} else {
|
||||
None
|
||||
@@ -299,6 +300,7 @@ mod tests {
|
||||
use rand::Rng;
|
||||
use sc_network::ObservedRole;
|
||||
use sp_runtime::{testing::H256, traits::{Block as BlockT}};
|
||||
use std::borrow::Cow;
|
||||
use std::convert::TryInto;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use substrate_test_runtime_client::runtime::Block;
|
||||
@@ -329,11 +331,11 @@ mod tests {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn write_notification(&self, _: PeerId, _: ConsensusEngineId, _: Vec<u8>) {
|
||||
fn write_notification(&self, _: PeerId, _: Cow<'static, str>, _: Vec<u8>) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn register_notifications_protocol(&self, _: ConsensusEngineId, _: Cow<'static, str>) {}
|
||||
fn register_notifications_protocol(&self, _: Cow<'static, str>) {}
|
||||
|
||||
fn announce(&self, _: B::Hash, _: Vec<u8>) {
|
||||
unimplemented!();
|
||||
@@ -361,8 +363,7 @@ mod tests {
|
||||
let network = TestNetwork::default();
|
||||
let mut gossip_engine = GossipEngine::<Block>::new(
|
||||
network.clone(),
|
||||
[1, 2, 3, 4],
|
||||
"my_protocol",
|
||||
"/my_protocol",
|
||||
Arc::new(AllowAll{}),
|
||||
);
|
||||
|
||||
@@ -383,14 +384,13 @@ mod tests {
|
||||
#[test]
|
||||
fn keeps_multiple_subscribers_per_topic_updated_with_both_old_and_new_messages() {
|
||||
let topic = H256::default();
|
||||
let engine_id = [1, 2, 3, 4];
|
||||
let protocol = Cow::Borrowed("/my_protocol");
|
||||
let remote_peer = PeerId::random();
|
||||
let network = TestNetwork::default();
|
||||
|
||||
let mut gossip_engine = GossipEngine::<Block>::new(
|
||||
network.clone(),
|
||||
engine_id.clone(),
|
||||
"my_protocol",
|
||||
protocol.clone(),
|
||||
Arc::new(AllowAll{}),
|
||||
);
|
||||
|
||||
@@ -404,7 +404,7 @@ mod tests {
|
||||
event_sender.start_send(
|
||||
Event::NotificationStreamOpened {
|
||||
remote: remote_peer.clone(),
|
||||
engine_id: engine_id.clone(),
|
||||
protocol: protocol.clone(),
|
||||
role: ObservedRole::Authority,
|
||||
}
|
||||
).expect("Event stream is unbounded; qed.");
|
||||
@@ -413,7 +413,7 @@ mod tests {
|
||||
let events = messages.iter().cloned().map(|m| {
|
||||
Event::NotificationsReceived {
|
||||
remote: remote_peer.clone(),
|
||||
messages: vec![(engine_id, m.into())]
|
||||
messages: vec![(protocol.clone(), m.into())]
|
||||
}
|
||||
}).collect::<Vec<_>>();
|
||||
|
||||
@@ -498,7 +498,7 @@ mod tests {
|
||||
}
|
||||
|
||||
fn prop(channels: Vec<ChannelLengthAndTopic>, notifications: Vec<Vec<Message>>) {
|
||||
let engine_id = [1, 2, 3, 4];
|
||||
let protocol = Cow::Borrowed("/my_protocol");
|
||||
let remote_peer = PeerId::random();
|
||||
let network = TestNetwork::default();
|
||||
|
||||
@@ -524,8 +524,7 @@ mod tests {
|
||||
|
||||
let mut gossip_engine = GossipEngine::<Block>::new(
|
||||
network.clone(),
|
||||
engine_id.clone(),
|
||||
"my_protocol",
|
||||
protocol.clone(),
|
||||
Arc::new(TestValidator{}),
|
||||
);
|
||||
|
||||
@@ -558,7 +557,7 @@ mod tests {
|
||||
event_sender.start_send(
|
||||
Event::NotificationStreamOpened {
|
||||
remote: remote_peer.clone(),
|
||||
engine_id: engine_id.clone(),
|
||||
protocol: protocol.clone(),
|
||||
role: ObservedRole::Authority,
|
||||
}
|
||||
).expect("Event stream is unbounded; qed.");
|
||||
@@ -576,7 +575,7 @@ mod tests {
|
||||
message.push(i_notification.try_into().unwrap());
|
||||
message.push(i_message.try_into().unwrap());
|
||||
|
||||
(engine_id, message.into())
|
||||
(protocol.clone(), message.into())
|
||||
}).collect();
|
||||
|
||||
event_sender.start_send(Event::NotificationsReceived {
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
//! - Implement the `Network` trait, representing the low-level networking primitives. It is
|
||||
//! already implemented on `sc_network::NetworkService`.
|
||||
//! - Implement the `Validator` trait. See the section below.
|
||||
//! - Decide on a `ConsensusEngineId`. Each gossiping protocol should have a different one.
|
||||
//! - Decide on a protocol name. Each gossiping protocol should have a different one.
|
||||
//! - Build a `GossipEngine` using these three elements.
|
||||
//! - Use the methods of the `GossipEngine` in order to send out messages and receive incoming
|
||||
//! messages.
|
||||
@@ -60,7 +60,7 @@ pub use self::validator::{DiscardAll, MessageIntent, Validator, ValidatorContext
|
||||
|
||||
use futures::prelude::*;
|
||||
use sc_network::{Event, ExHashT, NetworkService, PeerId, ReputationChange};
|
||||
use sp_runtime::{traits::Block as BlockT, ConsensusEngineId};
|
||||
use sp_runtime::{traits::Block as BlockT};
|
||||
use std::{borrow::Cow, pin::Pin, sync::Arc};
|
||||
|
||||
mod bridge;
|
||||
@@ -79,15 +79,14 @@ pub trait Network<B: BlockT> {
|
||||
fn disconnect_peer(&self, who: PeerId);
|
||||
|
||||
/// Send a notification to a peer.
|
||||
fn write_notification(&self, who: PeerId, engine_id: ConsensusEngineId, message: Vec<u8>);
|
||||
fn write_notification(&self, who: PeerId, protocol: Cow<'static, str>, message: Vec<u8>);
|
||||
|
||||
/// Registers a notifications protocol.
|
||||
///
|
||||
/// See the documentation of [`NetworkService:register_notifications_protocol`] for more information.
|
||||
fn register_notifications_protocol(
|
||||
&self,
|
||||
engine_id: ConsensusEngineId,
|
||||
protocol_name: Cow<'static, str>,
|
||||
protocol: Cow<'static, str>,
|
||||
);
|
||||
|
||||
/// Notify everyone we're connected to that we have the given block.
|
||||
@@ -110,16 +109,15 @@ impl<B: BlockT, H: ExHashT> Network<B> for Arc<NetworkService<B, H>> {
|
||||
NetworkService::disconnect_peer(self, who)
|
||||
}
|
||||
|
||||
fn write_notification(&self, who: PeerId, engine_id: ConsensusEngineId, message: Vec<u8>) {
|
||||
NetworkService::write_notification(self, who, engine_id, message)
|
||||
fn write_notification(&self, who: PeerId, protocol: Cow<'static, str>, message: Vec<u8>) {
|
||||
NetworkService::write_notification(self, who, protocol, message)
|
||||
}
|
||||
|
||||
fn register_notifications_protocol(
|
||||
&self,
|
||||
engine_id: ConsensusEngineId,
|
||||
protocol_name: Cow<'static, str>,
|
||||
protocol: Cow<'static, str>,
|
||||
) {
|
||||
NetworkService::register_notifications_protocol(self, engine_id, protocol_name)
|
||||
NetworkService::register_notifications_protocol(self, protocol)
|
||||
}
|
||||
|
||||
fn announce(&self, block: B::Hash, associated_data: Vec<u8>) {
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
use crate::{Network, MessageIntent, Validator, ValidatorContext, ValidationResult};
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::sync::Arc;
|
||||
use std::iter;
|
||||
@@ -26,7 +27,6 @@ use log::{error, trace};
|
||||
use lru::LruCache;
|
||||
use libp2p::PeerId;
|
||||
use sp_runtime::traits::{Block as BlockT, Hash, HashFor};
|
||||
use sp_runtime::ConsensusEngineId;
|
||||
use sc_network::ObservedRole;
|
||||
use wasm_timer::Instant;
|
||||
|
||||
@@ -89,7 +89,7 @@ impl<'g, 'p, B: BlockT> ValidatorContext<B> for NetworkContext<'g, 'p, B> {
|
||||
|
||||
/// Send addressed message to a peer.
|
||||
fn send_message(&mut self, who: &PeerId, message: Vec<u8>) {
|
||||
self.network.write_notification(who.clone(), self.gossip.engine_id, message);
|
||||
self.network.write_notification(who.clone(), self.gossip.protocol.clone(), message);
|
||||
}
|
||||
|
||||
/// Send all messages with given topic to a peer.
|
||||
@@ -100,7 +100,7 @@ impl<'g, 'p, B: BlockT> ValidatorContext<B> for NetworkContext<'g, 'p, B> {
|
||||
|
||||
fn propagate<'a, B: BlockT, I>(
|
||||
network: &mut dyn Network<B>,
|
||||
engine_id: ConsensusEngineId,
|
||||
protocol: Cow<'static, str>,
|
||||
messages: I,
|
||||
intent: MessageIntent,
|
||||
peers: &mut HashMap<PeerId, PeerConsensus<B::Hash>>,
|
||||
@@ -138,7 +138,7 @@ fn propagate<'a, B: BlockT, I>(
|
||||
peer.known_messages.insert(message_hash.clone());
|
||||
|
||||
trace!(target: "gossip", "Propagating to {}: {:?}", id, message);
|
||||
network.write_notification(id.clone(), engine_id, message.clone());
|
||||
network.write_notification(id.clone(), protocol.clone(), message.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -148,19 +148,19 @@ pub struct ConsensusGossip<B: BlockT> {
|
||||
peers: HashMap<PeerId, PeerConsensus<B::Hash>>,
|
||||
messages: Vec<MessageEntry<B>>,
|
||||
known_messages: LruCache<B::Hash, ()>,
|
||||
engine_id: ConsensusEngineId,
|
||||
protocol: Cow<'static, str>,
|
||||
validator: Arc<dyn Validator<B>>,
|
||||
next_broadcast: Instant,
|
||||
}
|
||||
|
||||
impl<B: BlockT> ConsensusGossip<B> {
|
||||
/// Create a new instance using the given validator.
|
||||
pub fn new(validator: Arc<dyn Validator<B>>, engine_id: ConsensusEngineId) -> Self {
|
||||
pub fn new(validator: Arc<dyn Validator<B>>, protocol: Cow<'static, str>) -> Self {
|
||||
ConsensusGossip {
|
||||
peers: HashMap::new(),
|
||||
messages: Default::default(),
|
||||
known_messages: LruCache::new(KNOWN_MESSAGES_CACHE_SIZE),
|
||||
engine_id,
|
||||
protocol,
|
||||
validator,
|
||||
next_broadcast: Instant::now() + REBROADCAST_INTERVAL,
|
||||
}
|
||||
@@ -235,7 +235,14 @@ impl<B: BlockT> ConsensusGossip<B> {
|
||||
fn rebroadcast(&mut self, network: &mut dyn Network<B>) {
|
||||
let messages = self.messages.iter()
|
||||
.map(|entry| (&entry.message_hash, &entry.topic, &entry.message));
|
||||
propagate(network, self.engine_id, messages, MessageIntent::PeriodicRebroadcast, &mut self.peers, &self.validator);
|
||||
propagate(
|
||||
network,
|
||||
self.protocol.clone(),
|
||||
messages,
|
||||
MessageIntent::PeriodicRebroadcast,
|
||||
&mut self.peers,
|
||||
&self.validator
|
||||
);
|
||||
}
|
||||
|
||||
/// Broadcast all messages with given topic.
|
||||
@@ -247,7 +254,7 @@ impl<B: BlockT> ConsensusGossip<B> {
|
||||
} else { None }
|
||||
);
|
||||
let intent = if force { MessageIntent::ForcedBroadcast } else { MessageIntent::Broadcast };
|
||||
propagate(network, self.engine_id, messages, intent, &mut self.peers, &self.validator);
|
||||
propagate(network, self.protocol.clone(), messages, intent, &mut self.peers, &self.validator);
|
||||
}
|
||||
|
||||
/// Prune old or no longer relevant consensus messages. Provide a predicate
|
||||
@@ -374,7 +381,7 @@ impl<B: BlockT> ConsensusGossip<B> {
|
||||
peer.known_messages.insert(entry.message_hash.clone());
|
||||
|
||||
trace!(target: "gossip", "Sending topic message to {}: {:?}", who, entry.message);
|
||||
network.write_notification(who.clone(), self.engine_id, entry.message.clone());
|
||||
network.write_notification(who.clone(), self.protocol.clone(), entry.message.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -390,7 +397,14 @@ impl<B: BlockT> ConsensusGossip<B> {
|
||||
let message_hash = HashFor::<B>::hash(&message);
|
||||
self.register_message_hashed(message_hash, topic, message.clone(), None);
|
||||
let intent = if force { MessageIntent::ForcedBroadcast } else { MessageIntent::Broadcast };
|
||||
propagate(network, self.engine_id, iter::once((&message_hash, &topic, &message)), intent, &mut self.peers, &self.validator);
|
||||
propagate(
|
||||
network,
|
||||
self.protocol.clone(),
|
||||
iter::once((&message_hash, &topic, &message)),
|
||||
intent,
|
||||
&mut self.peers,
|
||||
&self.validator
|
||||
);
|
||||
}
|
||||
|
||||
/// Send addressed message to a peer. The message is not kept or multicast
|
||||
@@ -411,7 +425,7 @@ impl<B: BlockT> ConsensusGossip<B> {
|
||||
trace!(target: "gossip", "Sending direct to {}: {:?}", who, message);
|
||||
|
||||
peer.known_messages.insert(message_hash);
|
||||
network.write_notification(who.clone(), self.engine_id, message);
|
||||
network.write_notification(who.clone(), self.protocol.clone(), message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -485,11 +499,11 @@ mod tests {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn write_notification(&self, _: PeerId, _: ConsensusEngineId, _: Vec<u8>) {
|
||||
fn write_notification(&self, _: PeerId, _: Cow<'static, str>, _: Vec<u8>) {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn register_notifications_protocol(&self, _: ConsensusEngineId, _: Cow<'static, str>) {}
|
||||
fn register_notifications_protocol(&self, _: Cow<'static, str>) {}
|
||||
|
||||
fn announce(&self, _: B::Hash, _: Vec<u8>) {
|
||||
unimplemented!();
|
||||
@@ -520,7 +534,7 @@ mod tests {
|
||||
|
||||
let prev_hash = H256::random();
|
||||
let best_hash = H256::random();
|
||||
let mut consensus = ConsensusGossip::<Block>::new(Arc::new(AllowAll), [0, 0, 0, 0]);
|
||||
let mut consensus = ConsensusGossip::<Block>::new(Arc::new(AllowAll), "/foo".into());
|
||||
let m1_hash = H256::random();
|
||||
let m2_hash = H256::random();
|
||||
let m1 = vec![1, 2, 3];
|
||||
@@ -547,7 +561,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn message_stream_include_those_sent_before_asking() {
|
||||
let mut consensus = ConsensusGossip::<Block>::new(Arc::new(AllowAll), [0, 0, 0, 0]);
|
||||
let mut consensus = ConsensusGossip::<Block>::new(Arc::new(AllowAll), "/foo".into());
|
||||
|
||||
// Register message.
|
||||
let message = vec![4, 5, 6];
|
||||
@@ -562,7 +576,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn can_keep_multiple_messages_per_topic() {
|
||||
let mut consensus = ConsensusGossip::<Block>::new(Arc::new(AllowAll), [0, 0, 0, 0]);
|
||||
let mut consensus = ConsensusGossip::<Block>::new(Arc::new(AllowAll), "/foo".into());
|
||||
|
||||
let topic = [1; 32].into();
|
||||
let msg_a = vec![1, 2, 3];
|
||||
@@ -576,7 +590,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn peer_is_removed_on_disconnect() {
|
||||
let mut consensus = ConsensusGossip::<Block>::new(Arc::new(AllowAll), [0, 0, 0, 0]);
|
||||
let mut consensus = ConsensusGossip::<Block>::new(Arc::new(AllowAll), "/foo".into());
|
||||
|
||||
let mut network = NoOpNetwork::default();
|
||||
|
||||
@@ -592,7 +606,7 @@ mod tests {
|
||||
fn on_incoming_ignores_discarded_messages() {
|
||||
let to_forward = ConsensusGossip::<Block>::new(
|
||||
Arc::new(DiscardAll),
|
||||
[0, 0, 0, 0],
|
||||
"/foo".into(),
|
||||
).on_incoming(
|
||||
&mut NoOpNetwork::default(),
|
||||
PeerId::random(),
|
||||
@@ -612,7 +626,7 @@ mod tests {
|
||||
|
||||
let to_forward = ConsensusGossip::<Block>::new(
|
||||
Arc::new(AllowAll),
|
||||
[0, 0, 0, 0],
|
||||
"/foo".into(),
|
||||
).on_incoming(
|
||||
&mut network,
|
||||
// Unregistered peer.
|
||||
|
||||
Reference in New Issue
Block a user