surrogate_gossiper.go
func (s *surrogateGossiper) OnGossip(update []byte) (GossipData, error) {
	hash := fnv.New64a()
	_, _ = hash.Write(update)
	updateHash := hash.Sum64()
	s.Lock()
	defer s.Unlock()
	for _, p := range s.prevUpdates {
		if updateHash == p.hash && bytes.Equal(update, p.update) {
			return nil, nil
		}
	}
	// Delete anything that's older than the gossip interval, so we don't grow forever
	// (this time limit is arbitrary; surrogateGossiper should pass on new gossip immediately
	// so there should be no reason for a duplicate to show up after a long time)
	updateTime := now()
	deleteBefore := updateTime.Add(-gossipInterval)
	keepFrom := len(s.prevUpdates)
	for i, p := range s.prevUpdates {
		if p.t.After(deleteBefore) {
			keepFrom = i
			break
		}
	}
	s.prevUpdates = append(s.prevUpdates[keepFrom:], prevUpdate{update, updateHash, updateTime})
	return newSurrogateGossipData(update), nil
}
func (s *surrogateGossiper) OnGossip(update []byte) (GossipData, error) {
	hash := fnv.New64a()
	_, _ = hash.Write(update)
	updateHash := hash.Sum64()
	s.Lock()
	defer s.Unlock()
	for _, p := range s.prevUpdates {
		if updateHash == p.hash && bytes.Equal(update, p.update) {
			return nil, nil
		}
	}
	// Delete anything that's older than the gossip interval, so we don't grow forever
	// (this time limit is arbitrary; surrogateGossiper should pass on new gossip immediately
	// so there should be no reason for a duplicate to show up after a long time)
	updateTime := now()
	deleteBefore := updateTime.Add(-gossipInterval)
	keepFrom := len(s.prevUpdates)
	for i, p := range s.prevUpdates {
		if p.t.After(deleteBefore) {
			keepFrom = i
			break
		}
	}
	s.prevUpdates = append(s.prevUpdates[keepFrom:], prevUpdate{update, updateHash, updateTime})
	return newSurrogateGossipData(update), nil
}
// OnGossip should return "everything new I've just learnt".
// surrogateGossiper doesn't understand the content of messages, but it can eliminate simple duplicates