feat: implement gossipsub partial messages extension#577
feat: implement gossipsub partial messages extension#577jxs wants to merge 70 commits intosigp:sigp-gossipsubfrom
Conversation
…sipsub-partial-messages
protocols/gossipsub/src/behaviour.rs
Outdated
| { | ||
| // Return err if trying to publish the same partial message state we currently have. | ||
| if existing.available_parts() == partial_message.available_parts() { | ||
| return Err(PublishError::Duplicate); |
There was a problem hiding this comment.
I don't think this is correct.
- Imagine you have parts 1,2,3.
- You tell your peers about those parts.
- A peer comes back and says I want part 2.
- You republish with the same parts in order to respond.
- You get this error and fail to respond.
There was a problem hiding this comment.
thanks for explaining Marco, updated as we spoke
protocols/gossipsub/src/behaviour.rs
Outdated
| data_transform: D, | ||
|
|
||
| /// Partial messages received. | ||
| partial_messages: HashMap<TopicHash, HashMap<Vec<u8>, P>>, |
There was a problem hiding this comment.
Do you need to store P here? I think it's better if P is owned solely by the application.
There was a problem hiding this comment.
yup, you are right, thanks Marco!
protocols/gossipsub/src/types.rs
Outdated
| pub(crate) struct PartialData { | ||
| pub(crate) ihave: Vec<u8>, | ||
| pub(crate) iwant: Vec<u8>, | ||
| pub(crate) message: Vec<u8>, |
There was a problem hiding this comment.
Is it useful to store the message here? It seems like wasted space, you only use it to check if the peer is sending you a duplicate.
Might be simpler to let the application handle dupes.
There was a problem hiding this comment.
thanks Marco, I only left wanted and has wanted to avoid sending the same message and has to avoid notifying the application layer of duplicates.
Thanks!
cb0e925 to
e6f1ae4
Compare
e6f1ae4 to
69c2d95
Compare
and create a paralel list for the partial_only topics.
dknopik
left a comment
There was a problem hiding this comment.
Some thoughts and some nitpicks.
protocols/gossipsub/src/types.rs
Outdated
| #[derive(Debug)] | ||
| pub enum RpcOut { | ||
| /// Publish a Gossipsub message on network.`timeout` limits the duration the message | ||
| /// PublishV a Gossipsub message on network.`timeout` limits the duration the message |
protocols/gossipsub/src/partial.rs
Outdated
|
|
||
| /// Returns metadata describing which parts of the message are available and which parts we want. | ||
| /// | ||
| /// This metadata is application-defined and should encode information about |
protocols/gossipsub/src/behaviour.rs
Outdated
| // If partial set, filter out peers who only want partial messages for the topic. | ||
| fn get_publish_peers(&mut self, topic_hash: &TopicHash, partial: bool) -> HashSet<PeerId> { |
There was a problem hiding this comment.
The fact that partial being true causes the filtering is confusing, as this is set to true on non-partial messages and vice-versa. I'd either call this filter_partial or invert the condition.
There was a problem hiding this comment.
yup, agreed and updated. Thanks Daniel!
protocols/gossipsub/src/partial.rs
Outdated
| /// - Optional remaining metadata if more parts are still available after this one | ||
| fn partial_message_bytes_from_metadata( | ||
| &self, | ||
| metadata: Option<impl AsRef<[u8]>>, |
There was a problem hiding this comment.
It is unclear to me what the expected behaviour is if metadata is None. I guess usually send everything we have to the peer?
There was a problem hiding this comment.
For Ethereum this is the case where we still haven't received a peer's metadata and could maybe eager push data to them. There are, at a high level, 3 options:
- Don't return anything.
- Return everything (probably not what we want to do)
- Return cells we didn't have locally (cells that we got from the network, not getBlobs).
protocols/gossipsub/src/partial.rs
Outdated
| fn partial_message_bytes_from_metadata( | ||
| &self, | ||
| metadata: Option<impl AsRef<[u8]>>, | ||
| ) -> Result<(impl AsRef<[u8]>, Option<impl AsRef<[u8]>>), PartialMessageError>; |
There was a problem hiding this comment.
If I understand correctly, if we have nothing to send to the peer, we return Ok((vec![], metadata)). This seems unintuitive and potentially inefficient to me, as we have to clone metadata and publish_partial has to compare it to the previous value. Maybe change it to allow returning Ok(None) to signal this?
protocols/gossipsub/src/behaviour.rs
Outdated
| timeout: Delay::new(self.config.publish_queue_duration()), | ||
| RpcOut::PartialMessage { | ||
| message: message_data, | ||
| metadata: partial_message.parts_metadata().as_ref().to_vec(), |
There was a problem hiding this comment.
Maybe get partial_message.parts_metadata() before the loop to avoid useless re-encoding (in case the implementation encodes ad-hoc)?
There was a problem hiding this comment.
yeah nice catch, before each peer had its own metadata so this was not possible. Updated!
protocols/gossipsub/src/partial.rs
Outdated
| /// | ||
| /// Returns `Ok(())` if the data was successfully integrated, or `Err`, | ||
| /// if the data was invalid or couldn't be processed. | ||
| fn extend_from_encoded_partial_message( |
There was a problem hiding this comment.
This is unused as far as I can tell. Yes, something like this is likely needed by the application, but as the behaviour does not need to access this, we can leave the exact interface up to the application (as maybe some external info is needed to extend the partial message).
Signed-off-by: Marco Munizaga <git@marcopolo.io>
33d825a to
5673256
Compare
Improve gossipsub behavior tests structure. Split the already big enough file into multiple test files according to their `Behaviour` tests category. Document the shared test primitives and rename structures, `InjectNodes` to `BehaviourTestBuilder` and remove the `inject_nodes` functions to use `Default`. This will help with the new tests for partial messages on sigp#577 which will be eventually moved here Pull-Request: #6232.
004f101 to
655bcb6
Compare
improve transient peers gathering missing code removal
supports partials we were gathering the opposite
d9e634e to
bd02db8
Compare
to only use one topic field per sent messages and peer partials
9a49c46 to
350a697
Compare
350a697 to
7a86d8b
Compare
…ation layer new changes if we didn't have anything to send to the peer
Description
This is a draft implementation of partial messages for gossipsub following the spec PR and based on the Go implementation. Still WIP but should give a good idea of the direction we're heading.