Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 7e3086d

Browse files
authoredJan 4, 2025··
feat: broadcasting idontwant for published messages
This PR introduces an optimisation to preemptively broadcast `IDONTWANT` for published messages, preventing redundant downloads of the same message received over gossip. This feature is opt-in and respects the existing `idontwant_message_size_threshold`. By default, `IDONTWANT` messages will only be sent for published messages larger than 1000 bytes. reference PRs: [spec](libp2p/specs#642) Pull-Request: #5773.
1 parent 40550dc commit 7e3086d

File tree

3 files changed

+45
-16
lines changed

3 files changed

+45
-16
lines changed
 

‎protocols/gossipsub/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
## 0.48.0
2+
3+
- Allow broadcasting `IDONTWANT` messages when publishing to avoid downloading data that is already available.
4+
See [PR 5773](https://github.com/libp2p/rust-libp2p/pull/5773)
5+
26
- Add configurable `idontwant_message_size_threshold` parameter.
37
See [PR 5770](https://github.com/libp2p/rust-libp2p/pull/5770)
48

‎protocols/gossipsub/src/behaviour.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,13 @@ where
757757
return Err(PublishError::AllQueuesFull(recipient_peers.len()));
758758
}
759759

760+
// Broadcast IDONTWANT messages
761+
if raw_message.raw_protobuf_len() > self.config.idontwant_message_size_threshold()
762+
&& self.config.idontwant_on_publish()
763+
{
764+
self.send_idontwant(&raw_message, &msg_id, raw_message.source.as_ref());
765+
}
766+
760767
tracing::debug!(message=%msg_id, "Published message");
761768

762769
if let Some(metrics) = self.metrics.as_mut() {
@@ -1741,7 +1748,7 @@ where
17411748

17421749
// Broadcast IDONTWANT messages
17431750
if raw_message.raw_protobuf_len() > self.config.idontwant_message_size_threshold() {
1744-
self.send_idontwant(&raw_message, &msg_id, propagation_source);
1751+
self.send_idontwant(&raw_message, &msg_id, Some(propagation_source));
17451752
}
17461753

17471754
// Check the validity of the message
@@ -2600,7 +2607,7 @@ where
26002607
&mut self,
26012608
message: &RawMessage,
26022609
msg_id: &MessageId,
2603-
propagation_source: &PeerId,
2610+
propagation_source: Option<&PeerId>,
26042611
) {
26052612
let Some(mesh_peers) = self.mesh.get(&message.topic) else {
26062613
return;
@@ -2611,8 +2618,8 @@ where
26112618
let recipient_peers: Vec<PeerId> = mesh_peers
26122619
.iter()
26132620
.chain(iwant_peers.iter())
2614-
.filter(|peer_id| {
2615-
*peer_id != propagation_source && Some(*peer_id) != message.source.as_ref()
2621+
.filter(|&peer_id| {
2622+
Some(peer_id) != propagation_source && Some(peer_id) != message.source.as_ref()
26162623
})
26172624
.cloned()
26182625
.collect();

‎protocols/gossipsub/src/config.rs

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ pub struct Config {
9999
connection_handler_publish_duration: Duration,
100100
connection_handler_forward_duration: Duration,
101101
idontwant_message_size_threshold: usize,
102+
idontwant_on_publish: bool,
102103
}
103104

104105
impl Config {
@@ -373,15 +374,22 @@ impl Config {
373374
self.connection_handler_forward_duration
374375
}
375376

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
377+
/// The message size threshold for which IDONTWANT messages are sent.
378+
/// Sending IDONTWANT messages for small messages can have a negative effect to the overall
379+
/// traffic and CPU load. This acts as a lower bound cutoff for the message size to which
380+
/// IDONTWANT won't be sent to peers. Only works if the peers support Gossipsub1.2
381+
/// (see <https://github.com/libp2p/specs/blob/master/pubsub/gossipsub/gossipsub-v1.2.md#idontwant-message>)
382+
/// default is 1kB
382383
pub fn idontwant_message_size_threshold(&self) -> usize {
383384
self.idontwant_message_size_threshold
384385
}
386+
387+
/// Send IDONTWANT messages after publishing message on gossip. This is an optimisation
388+
/// to avoid bandwidth consumption by downloading the published message over gossip.
389+
/// By default it is false.
390+
pub fn idontwant_on_publish(&self) -> bool {
391+
self.idontwant_on_publish
392+
}
385393
}
386394

387395
impl Default for Config {
@@ -455,6 +463,7 @@ impl Default for ConfigBuilder {
455463
connection_handler_publish_duration: Duration::from_secs(5),
456464
connection_handler_forward_duration: Duration::from_secs(1),
457465
idontwant_message_size_threshold: 1000,
466+
idontwant_on_publish: false,
458467
},
459468
invalid_protocol: false,
460469
}
@@ -841,17 +850,25 @@ impl ConfigBuilder {
841850
self
842851
}
843852

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
853+
/// The message size threshold for which IDONTWANT messages are sent.
854+
/// Sending IDONTWANT messages for small messages can have a negative effect to the overall
855+
/// traffic and CPU load. This acts as a lower bound cutoff for the message size to which
856+
/// IDONTWANT won't be sent to peers. Only works if the peers support Gossipsub1.2
857+
/// (see <https://github.com/libp2p/specs/blob/master/pubsub/gossipsub/gossipsub-v1.2.md#idontwant-message>)
858+
/// default is 1kB
850859
pub fn idontwant_message_size_threshold(&mut self, size: usize) -> &mut Self {
851860
self.config.idontwant_message_size_threshold = size;
852861
self
853862
}
854863

864+
/// Send IDONTWANT messages after publishing message on gossip. This is an optimisation
865+
/// to avoid bandwidth consumption by downloading the published message over gossip.
866+
/// By default it is false.
867+
pub fn idontwant_on_publish(&mut self, idontwant_on_publish: bool) -> &mut Self {
868+
self.config.idontwant_on_publish = idontwant_on_publish;
869+
self
870+
}
871+
855872
/// Constructs a [`Config`] from the given configuration and validates the settings.
856873
pub fn build(&self) -> Result<Config, ConfigBuilderError> {
857874
// check all constraints on config
@@ -926,6 +943,7 @@ impl std::fmt::Debug for Config {
926943
"idontwant_message_size_threhold",
927944
&self.idontwant_message_size_threshold,
928945
);
946+
let _ = builder.field("idontwant_on_publish", &self.idontwant_on_publish);
929947
builder.finish()
930948
}
931949
}

0 commit comments

Comments
 (0)
Please sign in to comment.