From c7e8129726c584e1fe41ffe3aadf686863906f9f Mon Sep 17 00:00:00 2001 From: Dzmitry Kalabuk Date: Fri, 25 Oct 2024 15:30:32 +0300 Subject: [PATCH] feat(gossipsub): apply `max_transmit_size` to the published message (#5642) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description When trying to publish a message using gossipsub's `publish` method, it should be possible to predict whether it will fit in the limit defined by the `max_transmit_size` config option. If this limit applies to the final protobuf payload, it's not possible to know that in advance because the size of the added fields is not fixed. This change makes the limit apply to the passed message size instead of the final wire size. ## Notes & open questions This is a minor version change because it changes the meaning of the existing config option. However, for the existing clients the limit will only become more permissive, so it shouldn't break anything. ## Change checklist - [x] I have performed a self-review of my own code - [x] I have made corresponding changes to the documentation - [ ] I have added tests that prove my fix is effective or that my feature works - [x] A changelog entry has been made in the appropriate crates --------- Co-authored-by: Darius Clark Co-authored-by: João Oliveira --- Cargo.lock | 2 +- Cargo.toml | 2 +- protocols/gossipsub/CHANGELOG.md | 5 +++++ protocols/gossipsub/Cargo.toml | 2 +- protocols/gossipsub/src/behaviour.rs | 10 +++++----- protocols/gossipsub/src/config.rs | 3 ++- 6 files changed, 15 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 54a0f8657a1..3b983a80d00 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2741,7 +2741,7 @@ dependencies = [ [[package]] name = "libp2p-gossipsub" -version = "0.47.1" +version = "0.48.0" dependencies = [ "async-std", "asynchronous-codec", diff --git a/Cargo.toml b/Cargo.toml index af7e47f8359..8869505921d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -83,7 +83,7 @@ libp2p-core = { version = "0.42.0", path = "core" } libp2p-dcutr = { version = "0.12.0", path = "protocols/dcutr" } libp2p-dns = { version = "0.42.0", path = "transports/dns" } libp2p-floodsub = { version = "0.45.0", path = "protocols/floodsub" } -libp2p-gossipsub = { version = "0.47.1", path = "protocols/gossipsub" } +libp2p-gossipsub = { version = "0.48.0", path = "protocols/gossipsub" } libp2p-identify = { version = "0.45.1", path = "protocols/identify" } libp2p-identity = { version = "0.2.9" } libp2p-kad = { version = "0.47.0", path = "protocols/kad" } diff --git a/protocols/gossipsub/CHANGELOG.md b/protocols/gossipsub/CHANGELOG.md index c47a9f40f66..cdd170c0d4b 100644 --- a/protocols/gossipsub/CHANGELOG.md +++ b/protocols/gossipsub/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.48.0 + +- Apply `max_transmit_size` to the inner message instead of the final payload. + See [PR 5642](https://github.com/libp2p/rust-libp2p/pull/5642). + ## 0.47.1 - Attempt to publish to at least mesh_n peers when flood publish is disabled. diff --git a/protocols/gossipsub/Cargo.toml b/protocols/gossipsub/Cargo.toml index 665f757fcb3..734ac36a231 100644 --- a/protocols/gossipsub/Cargo.toml +++ b/protocols/gossipsub/Cargo.toml @@ -3,7 +3,7 @@ name = "libp2p-gossipsub" edition = "2021" rust-version = { workspace = true } description = "Gossipsub protocol for libp2p" -version = "0.47.1" +version = "0.48.0" authors = ["Age Manning "] license = "MIT" repository = "https://github.com/libp2p/rust-libp2p" diff --git a/protocols/gossipsub/src/behaviour.rs b/protocols/gossipsub/src/behaviour.rs index 16adb555a44..6ddb25316e5 100644 --- a/protocols/gossipsub/src/behaviour.rs +++ b/protocols/gossipsub/src/behaviour.rs @@ -583,6 +583,11 @@ where .data_transform .outbound_transform(&topic, data.clone())?; + // check that the size doesn't exceed the max transmission size. + if transformed_data.len() > self.config.max_transmit_size() { + return Err(PublishError::MessageTooLarge); + } + let raw_message = self.build_raw_message(topic, transformed_data)?; // calculate the message id from the un-transformed data @@ -593,11 +598,6 @@ where topic: raw_message.topic.clone(), }); - // check that the size doesn't exceed the max transmission size - if raw_message.raw_protobuf_len() > self.config.max_transmit_size() { - return Err(PublishError::MessageTooLarge); - } - // Check the if the message has been published before if self.duplicate_cache.contains(&msg_id) { // This message has already been seen. We don't re-publish messages that have already diff --git a/protocols/gossipsub/src/config.rs b/protocols/gossipsub/src/config.rs index febe2514a30..1ee2e940661 100644 --- a/protocols/gossipsub/src/config.rs +++ b/protocols/gossipsub/src/config.rs @@ -174,7 +174,8 @@ impl Config { /// The maximum byte size for each gossipsub RPC (default is 65536 bytes). /// - /// This represents the maximum size of the entire protobuf payload. It must be at least + /// This represents the maximum size of the published message. It is additionally wrapped + /// in a protobuf struct, so the actual wire size may be a bit larger. It must be at least /// large enough to support basic control messages. If Peer eXchange is enabled, this /// must be large enough to transmit the desired peer information on pruning. It must be at /// least 100 bytes. Default is 65536 bytes.