diff --git a/router/peers.go b/router/peers.go index 340701bd..e7c5ae53 100644 --- a/router/peers.go +++ b/router/peers.go @@ -62,16 +62,12 @@ func (peers *Peers) ForEach(fun func(PeerName, *Peer)) { } } -// Merge an incoming update with our own topology, and -// create an "improved" update: -// - elements which the original payload added to the receiver are -// included -// - elements which the original payload updated in the receiver are -// included -// - elements which are equal between the receiver and the payload are -// not included -// - elements where the payload was older than the receiver's version -// are updated +// Merge an incoming update with our own topology. +// +// We add peers hitherto unknown to us, and update peers for which the +// update contains a more recent version than known to us. The return +// value is an "improved" update containing just these new/updated +// elements. func (peers *Peers) ApplyUpdate(update []byte) ([]byte, error) { peers.Lock() @@ -236,23 +232,12 @@ func (peers *Peers) applyUpdate(decodedUpdate []*Peer, decodedConns [][]byte) ma name := newPeer.Name // guaranteed to find peer in the peers.table peer := peers.table[name] - if peer != newPeer { - if peer.Version() > newPeer.Version() { - // we know more about this one than the update. If - // peer is ourself, this is slightly racey (further - // changes could occur to ourself in the mean - // time). But it doesn't matter as we know that we're - // already > newPeer.Version() and that's not going to - // change. - newUpdate[name] = peer - continue - } else if peer == peers.ourself { - // nobody but us updates us - continue - } else if peer.Version() == newPeer.Version() { - // implication is that connections are equal too - continue - } + if peer != newPeer && + (peer == peers.ourself || peer.Version() >= newPeer.Version()) { + // Nobody but us updates us. And if we know more about a + // peer than what's in the the update, we ignore the + // latter. + continue } // If we're here, either it was a new peer, or the update has // more info about the peer than we do. Either case, we need diff --git a/site/how-it-works.md b/site/how-it-works.md index 0d7af1fe..5e9560cf 100644 --- a/site/how-it-works.md +++ b/site/how-it-works.md @@ -125,19 +125,11 @@ peers that have just connected * when a connection is deleted - the update contains just the peer that lost the connection -The receiver merges it with its own topology model. If the payload is -a subset of the receiver's topology, no further action is -taken. Otherwise, the receiver sends out to all its connections an -"improved" update: - - - elements which the original payload added to the receiver are - included - - elements which the original payload updated in the receiver are - included - - elements which are equal between the receiver and the payload are - not included - - elements where the payload was older than the receiver's version - are updated +The receiver merges the update with its own topology model, adding +peers hitherto unknown to it, and updating peers for which the update +contains a more recent version than known to it. If there were any +such new/updated peers, then an improved update containing them is +sent out on all connections. If the update mentions a peer that the receiver does not know, then the entire update is rejected and the receiver sends a FetchAll