mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 10:01:17 +00:00
Limit gossip for non-authorities (#838)
* Limit gossip for non-authorities * Random shuffle
This commit is contained in:
committed by
Gav Wood
parent
79d538ee66
commit
e1e6c19f64
Generated
+1
@@ -2991,6 +2991,7 @@ dependencies = [
|
|||||||
"parity-codec 2.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parity-codec 2.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-codec-derive 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parity-codec-derive 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"rand 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-hex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"sr-primitives 0.1.0",
|
"sr-primitives 0.1.0",
|
||||||
"substrate-client 0.1.0",
|
"substrate-client 0.1.0",
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ bitflags = "1.0"
|
|||||||
futures = "0.1.17"
|
futures = "0.1.17"
|
||||||
linked-hash-map = "0.5"
|
linked-hash-map = "0.5"
|
||||||
rustc-hex = "1.0"
|
rustc-hex = "1.0"
|
||||||
|
rand = "0.5"
|
||||||
substrate-primitives = { path = "../../core/primitives" }
|
substrate-primitives = { path = "../../core/primitives" }
|
||||||
substrate-client = { path = "../../core/client" }
|
substrate-client = { path = "../../core/client" }
|
||||||
sr-primitives = { path = "../../core/sr-primitives" }
|
sr-primitives = { path = "../../core/sr-primitives" }
|
||||||
|
|||||||
@@ -20,6 +20,7 @@
|
|||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
use futures::sync::mpsc;
|
use futures::sync::mpsc;
|
||||||
use std::time::{Instant, Duration};
|
use std::time::{Instant, Duration};
|
||||||
|
use rand::{self, Rng};
|
||||||
use network_libp2p::NodeIndex;
|
use network_libp2p::NodeIndex;
|
||||||
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT};
|
use runtime_primitives::traits::{Block as BlockT, Header as HeaderT};
|
||||||
use runtime_primitives::generic::BlockId;
|
use runtime_primitives::generic::BlockId;
|
||||||
@@ -32,6 +33,7 @@ const MESSAGE_LIFETIME: Duration = Duration::from_secs(600);
|
|||||||
|
|
||||||
struct PeerConsensus<H> {
|
struct PeerConsensus<H> {
|
||||||
known_messages: HashSet<H>,
|
known_messages: HashSet<H>,
|
||||||
|
is_authority: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Consensus messages.
|
/// Consensus messages.
|
||||||
@@ -75,9 +77,9 @@ impl<B: BlockT> ConsensusGossip<B> where B::Header: HeaderT<Number=u64> {
|
|||||||
|
|
||||||
/// Handle new connected peer.
|
/// Handle new connected peer.
|
||||||
pub fn new_peer(&mut self, protocol: &mut Context<B>, who: NodeIndex, roles: Roles) {
|
pub fn new_peer(&mut self, protocol: &mut Context<B>, who: NodeIndex, roles: Roles) {
|
||||||
if roles.intersects(Roles::AUTHORITY | Roles::FULL) {
|
if roles.intersects(Roles::AUTHORITY) {
|
||||||
trace!(target:"gossip", "Registering {:?} {}", roles, who);
|
trace!(target:"gossip", "Registering {:?} {}", roles, who);
|
||||||
// Send out all known messages.
|
// Send out all known messages to authorities.
|
||||||
// TODO: limit by size
|
// TODO: limit by size
|
||||||
let mut known_messages = HashSet::new();
|
let mut known_messages = HashSet::new();
|
||||||
for entry in self.messages.iter() {
|
for entry in self.messages.iter() {
|
||||||
@@ -91,14 +93,39 @@ impl<B: BlockT> ConsensusGossip<B> where B::Header: HeaderT<Number=u64> {
|
|||||||
}
|
}
|
||||||
self.peers.insert(who, PeerConsensus {
|
self.peers.insert(who, PeerConsensus {
|
||||||
known_messages,
|
known_messages,
|
||||||
|
is_authority: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else if roles.intersects(Roles::FULL) {
|
||||||
|
self.peers.insert(who, PeerConsensus {
|
||||||
|
known_messages: HashSet::new(),
|
||||||
|
is_authority: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn propagate(&mut self, protocol: &mut Context<B>, message: message::Message<B>, hash: B::Hash) {
|
fn propagate(&mut self, protocol: &mut Context<B>, message: message::Message<B>, hash: B::Hash) {
|
||||||
|
let mut non_authorities: Vec<_> = self.peers.iter()
|
||||||
|
.filter_map(|(id, ref peer)| if !peer.is_authority && !peer.known_messages.contains(&hash) { Some(*id) } else { None })
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
rand::thread_rng().shuffle(&mut non_authorities);
|
||||||
|
let non_authorities: HashSet<_> = if non_authorities.is_empty() {
|
||||||
|
HashSet::new()
|
||||||
|
} else {
|
||||||
|
non_authorities[0..non_authorities.len().min(((non_authorities.len() as f64).sqrt() as usize).max(3))].iter().collect()
|
||||||
|
};
|
||||||
|
|
||||||
for (id, ref mut peer) in self.peers.iter_mut() {
|
for (id, ref mut peer) in self.peers.iter_mut() {
|
||||||
if peer.known_messages.insert(hash.clone()) {
|
if peer.is_authority {
|
||||||
|
if peer.known_messages.insert(hash.clone()) {
|
||||||
|
trace!(target:"gossip", "Propagating to authority {}: {:?}", id, message);
|
||||||
|
protocol.send_message(*id, message.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if non_authorities.contains(&id) {
|
||||||
trace!(target:"gossip", "Propagating to {}: {:?}", id, message);
|
trace!(target:"gossip", "Propagating to {}: {:?}", id, message);
|
||||||
|
peer.known_messages.insert(hash.clone());
|
||||||
protocol.send_message(*id, message.clone());
|
protocol.send_message(*id, message.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ extern crate substrate_network_libp2p as network_libp2p;
|
|||||||
extern crate parity_codec as codec;
|
extern crate parity_codec as codec;
|
||||||
extern crate futures;
|
extern crate futures;
|
||||||
extern crate rustc_hex;
|
extern crate rustc_hex;
|
||||||
|
extern crate rand;
|
||||||
#[macro_use] extern crate log;
|
#[macro_use] extern crate log;
|
||||||
#[macro_use] extern crate bitflags;
|
#[macro_use] extern crate bitflags;
|
||||||
#[macro_use] extern crate error_chain;
|
#[macro_use] extern crate error_chain;
|
||||||
|
|||||||
@@ -296,11 +296,11 @@ impl<B: BlockT> ChainSync<B> {
|
|||||||
if !self.is_known_or_already_downloading(protocol, header.parent_hash()) {
|
if !self.is_known_or_already_downloading(protocol, header.parent_hash()) {
|
||||||
trace!(target: "sync", "Ignoring unknown stale block announce from {}: {} {:?}", who, hash, header);
|
trace!(target: "sync", "Ignoring unknown stale block announce from {}: {} {:?}", who, hash, header);
|
||||||
} else {
|
} else {
|
||||||
trace!(target: "sync", "Downloading new stale block announced from {}: {} {:?}", who, hash, header);
|
trace!(target: "sync", "Considering new stale block announced from {}: {} {:?}", who, hash, header);
|
||||||
self.download_stale(protocol, who, &hash);
|
self.download_stale(protocol, who, &hash);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
trace!(target: "sync", "Downloading new block announced from {}: {} {:?}", who, hash, header);
|
trace!(target: "sync", "Considering new block announced from {}: {} {:?}", who, hash, header);
|
||||||
self.download_new(protocol, who);
|
self.download_new(protocol, who);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -371,6 +371,7 @@ impl<B: BlockT> ChainSync<B> {
|
|||||||
let import_status = self.import_queue.status();
|
let import_status = self.import_queue.status();
|
||||||
// when there are too many blocks in the queue => do not try to download new blocks
|
// when there are too many blocks in the queue => do not try to download new blocks
|
||||||
if import_status.importing_count > MAX_IMPORTING_BLOCKS {
|
if import_status.importing_count > MAX_IMPORTING_BLOCKS {
|
||||||
|
trace!(target: "sync", "Too many blocks in the queue.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// we should not download already queued blocks
|
// we should not download already queued blocks
|
||||||
@@ -395,7 +396,7 @@ impl<B: BlockT> ChainSync<B> {
|
|||||||
trace!(target: "sync", "Nothing to request");
|
trace!(target: "sync", "Nothing to request");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => (),
|
_ => trace!(target: "sync", "Peer {} is busy", who),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user