Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Staggered message sending with elimination of peers during transmission based on idontwants #1100

Draft
wants to merge 2 commits into
base: p2p-research
Choose a base branch
from

Conversation

ufarooqstatus
Copy link
Collaborator

  1. We use semaphores to limit simultaneous transmissions to two
  2. During message transmission, we check received idontwants to cancel unnecessary transmissions
  3. we relay to outbound peers first to minimize chances of two peers sending to each other

closes PR1093

…eers (even during transmissions) based on idontwants
@ufarooqstatus ufarooqstatus mentioned this pull request May 20, 2024
@@ -529,6 +538,11 @@ method rpcHandler*(g: GossipSub,

libp2p_gossipsub_duplicate.inc()

#Dont relay to the peers from which we already received
#We do it for large messages only
if msg.data.len > msgId.len * 10:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the message is in seen, it should not be sent to anyone meaning we should not need to track it individually (doing so costs significant amounts of memory)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually, right - the seen check has been done and we need to stop the message after the seen check . hm . it would likely be better that we keep track of in-flight / queued messages and cancel these sends specifically on idontwant rather than storing all idontwant hashes

Copy link
Contributor

@diegomrsantos diegomrsantos May 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we already have this here?

g.handleIDontWant(peer, control.idontwant)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually, right - the seen check has been done and we need to stop the message after the seen check . hm . it would likely be better that we keep track of in-flight / queued messages and cancel these sends specifically on idontwant rather than storing all idontwant hashes

Haven't this been already tried here? #851 (comment)

Copy link
Contributor

@diegomrsantos diegomrsantos May 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe heDontWants is meant to handle idontwant msgs received and we already have the seen data structure to avoid relaying duplicates.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This data structure is probably to store ID of msgs other peers in the network have already seen but we haven't yet. Then when we do see it, we don't send it to them.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO our send inserts the message in non-priority queue, and may consume some time before its aired. if we receive the message during this interval, we can still cancel transmit

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, but

g.handleIDontWant(peer, control.idontwant)
and checking idontwant when dequeuing from non-prio are enough. We don't seem to need this code for that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could even end up not sending the msg to the current peer as it is enqueued and before sending we check idontwant.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, this part does not have much impact!

@arnetheduck
Copy link
Contributor

broadly, limiting concurrent sends this way means two peers can hold up the queue for everyone else, including the fast peers - this is a key reason we haven't gone down this route.

the limit would have to be a lot higher - ie somewhere on the order of dmax probably - we would also need to consider a timeout policy of individual sends stronger than what we have today.

@@ -418,10 +418,19 @@ proc validateAndRelay(g: GossipSub,
break
toSendPeers.excl(seenPeers)

#We first send to the outbound peers to avoid peers sending same message to each other
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please elaborate on why that is the case?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was intended to avoid A sending to B and B sending to A at the same time,,, but yes, its not making much impact,,, due to the preceding IDontWants

p.semTxLimit[].release()
await conn.close()

proc sendEncoded*(p: PubSubPeer, msg: seq[byte], isHighPriority: bool, saltedId: Option[SaltedId] = none(SaltedId)): Future[void] =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is saltedId optional?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is saltedId optional?

same SendMsg for control and published messages, so for some messages we did not need saltedID

Copy link
Contributor

@diegomrsantos diegomrsantos May 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, we can improve this design as I believe high-prio are only control and msgs published by the local peer. It means no other peer can send an idontwant for them. It means we can move the idontwant to the non-prio branch in this proc. Wdyt?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, If we were enqueueing those msgs and we didn't dequeue them fast enough, peers could receive them via peers we sent first. But as we always send them immediately, it seems this can't happen. Makes sense?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, we can improve this design as I believe high-prio are only control and msgs published by the local peer. It means no other peer can send an idontwant for them. It means we can move the idontwant to the non-prio branch in this proc. Wdyt?

yes, we dont need to check hedontwants for the messages published by the local peer,,, but i guess IDontWant should be transmitted with the highest priority

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, i believe, IDontWant should be issued before this step. Because even if a message is not valid, we can react early to stop the spread of such message. And in case of valid messages, we get to learn early that our peers have received this message

Copy link
Contributor

@diegomrsantos diegomrsantos May 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant that checking idontwant before sending a msg could be done only for relayed msgs, at line 417 of this file.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes for relayed messages only

@ufarooqstatus
Copy link
Collaborator Author

broadly, limiting concurrent sends this way means two peers can hold up the queue for everyone else, including the fast peers - this is a key reason we haven't gone down this route.

This is configurable, but i could find very similar results for 2-5 simultaneous sends

the limit would have to be a lot higher - ie somewhere on the order of dmax probably - we would also need to consider a timeout policy of individual sends stronger than what we have today.

I have tried this way to time-limit

@ufarooqstatus
Copy link
Collaborator Author

I have tried this way to time-limit

In fact (at-least) a slow peer can identify itself as a slow peer if it can not finish all sends within a strict time-limit. Also the peers for which we always miss the timebound. Thinking to try different locks for fast/slow peers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Experimental
Development

Successfully merging this pull request may close these issues.

3 participants