protocols/gossipsub: Improve bandwidth (#2327)

This PR adds some bandwidth improvements to gossipsub.

After a bit of inspection on live networks a number of improvements have been
made that can help reduce unnecessary bandwidth on gossipsub networks. This PR
introduces the following:

- A 1:1 tracking of all in-flight IWANT requests. This not only ensures that all
  IWANT requests are answered and peers penalized accordingly, but gossipsub
  will no no longer create multiple IWANT requests for multiple peers.
  Previously, gossipsub sampled the in-flight IWANT requests in order to
  penalize peers for not responding with a high probability that we would detect
  non-responsive nodes. Futher, it was possible to re-request IWANT messages
  that are already being requested causing added duplication in messages and
  wasted unnecessary IWANT control messages. This PR shifts this logic to only
  request message ids that we are not currently requesting from peers.

- Triangle routing naturally gives rise to unnecessary duplicates. Consider a
  mesh of 4 peers that are interconnected. Peer 1 sends a new message to 2,3,4.
  2 propagates to 3,4 and 3 propagates to 2,4 and 4 propagates to 2,3. In this
  case 3 has received the message 3 times. If we keep track of peers that send
  us messages, when publishing or forwarding we no longer send to peers that
  have sent us a duplicate, we can eliminate one of the sends in the scenario
  above. This only occurs when message validation is async however. This PR adds
  this logic to remove some elements of triangle-routing duplicates.

Co-authored-by: Divma <26765164+divagant-martian@users.noreply.github.com>
Co-authored-by: Max Inden <mail@max-inden.de>
Co-authored-by: Diva M <divma@protonmail.com>
This commit is contained in:
Age Manning
2021-12-21 22:09:15 +11:00
committed by GitHub
parent e15dad5f45
commit 379001a1d0
8 changed files with 227 additions and 128 deletions

View File

@ -265,7 +265,7 @@ impl PeerScore {
let p3 = deficit * deficit;
topic_score += p3 * topic_params.mesh_message_deliveries_weight;
debug!(
"The peer {} has a mesh message deliveries deficit of {} in topic\
"[Penalty] The peer {} has a mesh message deliveries deficit of {} in topic\
{} and will get penalized by {}",
peer_id,
deficit,
@ -314,7 +314,7 @@ impl PeerScore {
let surplus = (peers_in_ip as f64) - self.params.ip_colocation_factor_threshold;
let p6 = surplus * surplus;
debug!(
"The peer {} gets penalized because of too many peers with the ip {}. \
"[Penalty] The peer {} gets penalized because of too many peers with the ip {}. \
The surplus is {}. ",
peer_id, ip, surplus
);
@ -335,7 +335,7 @@ impl PeerScore {
pub fn add_penalty(&mut self, peer_id: &PeerId, count: usize) {
if let Some(peer_stats) = self.peer_stats.get_mut(peer_id) {
debug!(
"Behavioral penalty for peer {}, count = {}.",
"[Penalty] Behavioral penalty for peer {}, count = {}.",
peer_id, count
);
peer_stats.behaviour_penalty += count as f64;
@ -597,7 +597,7 @@ impl PeerScore {
/// Similar to `reject_message` except does not require the message id or reason for an invalid message.
pub fn reject_invalid_message(&mut self, from: &PeerId, topic_hash: &TopicHash) {
debug!(
"Message from {} rejected because of ValidationError or SelfOrigin",
"[Penalty] Message from {} rejected because of ValidationError or SelfOrigin",
from
);
self.mark_invalid_message_delivery(from, topic_hash);
@ -764,7 +764,7 @@ impl PeerScore {
peer_stats.stats_or_default_mut(topic_hash.clone(), &self.params)
{
debug!(
"Peer {} delivered an invalid message in topic {} and gets penalized \
"[Penalty] Peer {} delivered an invalid message in topic {} and gets penalized \
for it",
peer_id, topic_hash
);