Large Message Handling (IDontWant + IMReceiving)

Suppose that Host A has full-message mesh M_A=\{B, C, A_1, A_2, A_3,....,A_6\}. In the current arrangement, on receiving a very large message X from host B, A sends an IDontWant message to M_A - B peers, and after that, it starts relaying X to all the peers in M_A - B. If A receives an IDontWant from any host C during the transmission, it excludes C from its transmission queue to avoid redundant transmission to C. The use of IDontWant reduces redundant transmissions to some extent. However, the use of IDontWant message alone has an inherent limitation:

A peer can only send an IDontWant when it has received and validated a message. A large message transmission consumes significant time. For instance, transmitting a 1MB message with 100 Mbps bandwidth may consume 80 to several hundred milliseconds/peer (depending upon C_{wnd} and latency). There is a high probability that peers in M_A - \{B,C\} also receive X from many other peer during the same time.

A few solutions intended to cater to this problem include:

  1. Instead of simultaneously relaying a message to all peers, sequential sending (relaying to one or a minimal number of peers at a time) can help achieve maximum bandwidth for each peer. Hence, each transmission concludes quickly (accumulative transmission time remains the same), enabling immediate retransmissions from receiver.
  2. Use sequential sending and stagger (or even add delays) between relayed/published message transmissions to allow maximum IDontWant receptions

However, sequential sending (or staggering) with the wrong peer order occasionally introduces latency spikes in message propagation. This is because slow receiver(s) at the start of the message transmission queue can introduce significant delays in message propagation. This can happen due to low bandwidth (or low C_{wnd}). At the same time, simultaneous selection of the same peer from many senders can slow down these senders.

To remedy this problem, any peer receiving IDontWant (say A_3) can send a small IMReceiving message to its full message peers M_{A3}. IMReceiving reception will conclude quickly by all peers in M_{A3}. Any K \in M_{A3} places A_3 at the end of the message transmission queue to increase the chances of IDontWant reception from A_3

A peer can only send an IDontWant when it has received and validated a message.

It does not need to validate the message - merely compute its message id - even if (specially if) the message is invalid, we don’t want extra copies.

IMReceiving

This opens up an attack where a peer starts sending a message but never finishes, leading to the message never being received in full

One thing we’ve considered is sending the message id before sending the message (on the same stream) - this would allow a client to send IDONTWANT to some peers at least - potentially with an IWANT followup in case the original message does not appear within some time limit.

Yes, I am afraid we are sending IDontWants after the validation. Will check the impact by doing it early!

For a very large message, the intention is to relay it sequentially, starting with the fastest peer (so the receiver gets it faster and starts relaying it). So, the right peer order can be crucial. I tried guessing faster peers by buffer fill rate and some other mechanisms. It is only sometimes helpful, and in many situations, multiple senders get hold of the same receiver (for the same message).

When receiving an IMReceiving, the sender does not cancel the transmission but just places that peer at the end of the transmission queue.