// Revokes the list of unreachable peers from routing table t. func (o *Overlay) revoke(t *table, down []*big.Int) { downs := sortext.BigIntSlice(down) downs.Sort() // Clean up the leaf set intact := true for i := 0; i < len(t.leaves); i++ { idx := downs.Search(t.leaves[i]) if idx < len(downs) && downs[idx].Cmp(t.leaves[i]) == 0 { t.leaves[i] = t.leaves[len(t.leaves)-1] t.leaves = t.leaves[:len(t.leaves)-1] intact = false i-- } } if !intact { // Repair the leafset as best as possible from the pool of active connections o.lock.RLock() all := make([]*big.Int, 0, len(o.livePeers)) for _, p := range o.livePeers { all = append(all, p.nodeId) } o.lock.RUnlock() t.leaves = o.mergeLeaves(t.leaves, all) } // Clean up the routing table for r, row := range t.routes { for c, id := range row { if id != nil { if idx := downs.Search(id); idx < len(downs) && downs[idx].Cmp(id) == 0 { // Try and fix routing entry from connection pool t.routes[r][c] = nil o.lock.RLock() for _, p := range o.livePeers { if pre, dig := prefix(o.nodeId, p.nodeId); pre == r && dig == c { t.routes[r][c] = p.nodeId break } } o.lock.RUnlock() } } } } }
// Searches a potential routing table for nodes not yet connected. func (o *Overlay) discover(t *table) []*big.Int { o.lock.RLock() defer o.lock.RUnlock() ids := []*big.Int{} for _, id := range t.leaves { if id.Cmp(o.nodeId) != 0 { if _, ok := o.livePeers[id.String()]; !ok { ids = append(ids, id) } } } for _, row := range t.routes { for _, id := range row { if id != nil { if _, ok := o.livePeers[id.String()]; !ok { ids = append(ids, id) } } } } sortext.BigInts(ids) return ids[:sortext.Unique(sortext.BigIntSlice(ids))] }