With every iteration of the heartbeat routine for a peer running gossipsub, it will ascertain whether it has enough peers in its mesh for a topic. If there are not enough peers it will retrieve the relevant peers and add them to its mesh. Doing this for the same peer for multiple topics, we can batch all the GRAFT messages for the different topics into a single RPC message.
Problem
In sendGraftPrune while looping through all the topics to send a message out for, we take the pointer to string value of the topic and utilize that in our control message. Unfortunately in a loop that reference doesn't hold for each topic, instead changing for each iteration in a loop. So we instead end up referring to the last element in the original topic slice for all the GRAFT topic ids in our new ControlGraft message. To illustrate this:
The solution is simple where we copy each topic before referencing them, this mitigates the problem with the other topics being overwritten in the message. Also a regression test has been added to test this exact case. There maybe more cases like this in the repo but I couldn't find anything similar so far when I scanned though the code.
Background
With every iteration of the heartbeat routine for a peer running gossipsub, it will ascertain whether it has enough peers in its mesh for a topic. If there are not enough peers it will retrieve the relevant peers and add them to its mesh. Doing this for the same peer for multiple topics, we can batch all the
GRAFT
messages for the different topics into a single RPC message.Problem
In
sendGraftPrune
while looping through all the topics to send a message out for, we take the pointer to string value of the topic and utilize that in our control message. Unfortunately in a loop that reference doesn't hold for each topic, instead changing for each iteration in a loop. So we instead end up referring to the last element in the original topic slice for all theGRAFT
topic ids in our newControlGraft
message. To illustrate this:https://play.golang.org/p/1cPEh5fYIvx
Solution
The solution is simple where we copy each topic before referencing them, this mitigates the problem with the other topics being overwritten in the message. Also a regression test has been added to test this exact case. There maybe more cases like this in the repo but I couldn't find anything similar so far when I scanned though the code.