Skip to content

Commit e1d02ca

Browse files
authored
feat(gossipsub): Allow setting a size threshold for IDONTWANT messages
This PR adds configurable parameter that sets minimum message size for which `IDONTWANT` messages would be send. This is an optimisation trick, discussion regarding the same can be found [here](sigp/lighthouse#6437) Pull-Request: #5770.
1 parent 1ab4658 commit e1d02ca

File tree

4 files changed

+77
-3
lines changed

4 files changed

+77
-3
lines changed

protocols/gossipsub/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
## 0.48.0
2+
- Add configurable `idontwant_message_size_threshold` parameter.
3+
See [PR 5770](https://github.com/libp2p/rust-libp2p/pull/5770)
24

35
- Introduce Gossipsub v1.2 [spec](https://github.com/libp2p/specs/blob/master/pubsub/gossipsub/gossipsub-v1.2.md).
46
See [PR 5697](https://github.com/libp2p/rust-libp2p/pull/5697)

protocols/gossipsub/src/behaviour.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1739,8 +1739,10 @@ where
17391739
// Calculate the message id on the transformed data.
17401740
let msg_id = self.config.message_id(&message);
17411741

1742-
// Broadcast IDONTWANT messages.
1743-
self.send_idontwant(&raw_message, &msg_id, propagation_source);
1742+
// Broadcast IDONTWANT messages
1743+
if raw_message.raw_protobuf_len() > self.config.idontwant_message_size_threshold() {
1744+
self.send_idontwant(&raw_message, &msg_id, propagation_source);
1745+
}
17441746

17451747
// Check the validity of the message
17461748
// Peers get penalized if this message is invalid. We don't add it to the duplicate cache
@@ -1757,6 +1759,7 @@ where
17571759
self.mcache.observe_duplicate(&msg_id, propagation_source);
17581760
return;
17591761
}
1762+
17601763
tracing::debug!(
17611764
message=%msg_id,
17621765
"Put message in duplicate_cache and resolve promises"

protocols/gossipsub/src/behaviour/tests.rs

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5288,7 +5288,7 @@ fn sends_idontwant() {
52885288

52895289
let message = RawMessage {
52905290
source: Some(peers[1]),
5291-
data: vec![12],
5291+
data: vec![12u8; 1024],
52925292
sequence_number: Some(0),
52935293
topic: topic_hashes[0].clone(),
52945294
signature: None,
@@ -5314,6 +5314,48 @@ fn sends_idontwant() {
53145314
);
53155315
}
53165316

5317+
#[test]
5318+
fn doesnt_sends_idontwant_for_lower_message_size() {
5319+
let (mut gs, peers, receivers, topic_hashes) = inject_nodes1()
5320+
.peer_no(5)
5321+
.topics(vec![String::from("topic1")])
5322+
.to_subscribe(true)
5323+
.gs_config(Config::default())
5324+
.explicit(1)
5325+
.peer_kind(PeerKind::Gossipsubv1_2)
5326+
.create_network();
5327+
5328+
let local_id = PeerId::random();
5329+
5330+
let message = RawMessage {
5331+
source: Some(peers[1]),
5332+
data: vec![12],
5333+
sequence_number: Some(0),
5334+
topic: topic_hashes[0].clone(),
5335+
signature: None,
5336+
key: None,
5337+
validated: true,
5338+
};
5339+
5340+
gs.handle_received_message(message.clone(), &local_id);
5341+
assert_eq!(
5342+
receivers
5343+
.into_iter()
5344+
.fold(0, |mut idontwants, (peer_id, c)| {
5345+
let non_priority = c.non_priority.get_ref();
5346+
while !non_priority.is_empty() {
5347+
if let Ok(RpcOut::IDontWant(_)) = non_priority.try_recv() {
5348+
assert_ne!(peer_id, peers[1]);
5349+
idontwants += 1;
5350+
}
5351+
}
5352+
idontwants
5353+
}),
5354+
0,
5355+
"IDONTWANT was sent"
5356+
);
5357+
}
5358+
53175359
/// Test that a node doesn't send IDONTWANT messages to the mesh peers
53185360
/// that don't run Gossipsub v1.2.
53195361
#[test]

protocols/gossipsub/src/config.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ pub struct Config {
9898
connection_handler_queue_len: usize,
9999
connection_handler_publish_duration: Duration,
100100
connection_handler_forward_duration: Duration,
101+
idontwant_message_size_threshold: usize,
101102
}
102103

103104
impl Config {
@@ -371,6 +372,16 @@ impl Config {
371372
pub fn forward_queue_duration(&self) -> Duration {
372373
self.connection_handler_forward_duration
373374
}
375+
376+
// The message size threshold for which IDONTWANT messages are sent.
377+
// Sending IDONTWANT messages for small messages can have a negative effect to the overall
378+
// traffic and CPU load. This acts as a lower bound cutoff for the message size to which
379+
// IDONTWANT won't be sent to peers. Only works if the peers support Gossipsub1.2
380+
// (see https://github.com/libp2p/specs/blob/master/pubsub/gossipsub/gossipsub-v1.2.md#idontwant-message)
381+
// default is 1kB
382+
pub fn idontwant_message_size_threshold(&self) -> usize {
383+
self.idontwant_message_size_threshold
384+
}
374385
}
375386

376387
impl Default for Config {
@@ -443,6 +454,7 @@ impl Default for ConfigBuilder {
443454
connection_handler_queue_len: 5000,
444455
connection_handler_publish_duration: Duration::from_secs(5),
445456
connection_handler_forward_duration: Duration::from_secs(1),
457+
idontwant_message_size_threshold: 1000,
446458
},
447459
invalid_protocol: false,
448460
}
@@ -829,6 +841,17 @@ impl ConfigBuilder {
829841
self
830842
}
831843

844+
// The message size threshold for which IDONTWANT messages are sent.
845+
// Sending IDONTWANT messages for small messages can have a negative effect to the overall
846+
// traffic and CPU load. This acts as a lower bound cutoff for the message size to which
847+
// IDONTWANT won't be sent to peers. Only works if the peers support Gossipsub1.2
848+
// (see https://github.com/libp2p/specs/blob/master/pubsub/gossipsub/gossipsub-v1.2.md#idontwant-message)
849+
// default is 1kB
850+
pub fn idontwant_message_size_threshold(&mut self, size: usize) -> &mut Self {
851+
self.config.idontwant_message_size_threshold = size;
852+
self
853+
}
854+
832855
/// Constructs a [`Config`] from the given configuration and validates the settings.
833856
pub fn build(&self) -> Result<Config, ConfigBuilderError> {
834857
// check all constraints on config
@@ -899,6 +922,10 @@ impl std::fmt::Debug for Config {
899922
"published_message_ids_cache_time",
900923
&self.published_message_ids_cache_time,
901924
);
925+
let _ = builder.field(
926+
"idontwant_message_size_threhold",
927+
&self.idontwant_message_size_threshold,
928+
);
902929
builder.finish()
903930
}
904931
}

0 commit comments

Comments
 (0)