There are two distinct cases here: we replace 'ourself' with the same IP, or we replace a dead node with a new IP (ala ec2.) We can't know which one we're doing a priori, so we shadow gossip. If we're replacing the same IP, our shadow SYN will contain it, and the remote node will ACK with what we need.
If we're not replacing with the same IP, there's a problem: an ACK will only contain what was present in the SYN digest list. One could argue this is the sender being naive, since it obviously knows the node that sent the SYN doesn't have some states that it does, but I think at scale this makes sense since it's possible a third node has begun gossiping with the SYN sender, too. In any case, I don't want to change that behavior at this point.
The other problem is, we can't just sit around and wait for someone to send us a populated SYN either, since we're not a part of gossip and we're new. But we don't know we're new yet, and can't insert ourselves into gossip either, or we'll break the case of using the same IP.
So, we'll create a special case for shadow gossip, and redefine it a bit. Instead of sending a SYN with our own endpoint and a generation of zero, we'll send a completely empty SYN (digest-wise, we still populate the cluster name and partioner, since those checks still make sense.) This won't ever normally occur in gossip, because a node always knows about and adds itself. When we see an empty SYN, we can know that the node that sent it is asking for everything we've got, and we can ACK with just that, allowing the replacement node to have whatever it needs for either the same or different IP cases.
v3 does this.