From 7ce1b74cdfbc9617e2225b793e8b11b0e7d73edb Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Tue, 29 Jan 2019 17:08:04 -0800 Subject: [PATCH] fix infinite loop in addrbook There are cases where we only have a small number of addresses marked good ("old"), but the selection mechanism keeps trying to select more of these addresses, and hence ends up in an infinite loop. Here we fix this to only try and select such "old" addresses if we have enough of them. Note this means, if we don't have enough of them, we may return more "new" addresses than otherwise expected by the newSelectionBias. This whole GetSelectionWithBias method probably needs to be rewritten, but this is a quick fix for the issue. --- p2p/pex/addrbook.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/p2p/pex/addrbook.go b/p2p/pex/addrbook.go index cfeefb343..c93bcdcb9 100644 --- a/p2p/pex/addrbook.go +++ b/p2p/pex/addrbook.go @@ -411,8 +411,12 @@ func (a *addrBook) GetSelectionWithBias(biasTowardsNewAddrs int) []*p2p.NetAddre selectionIndex := 0 ADDRS_LOOP: for selectionIndex < numAddresses { + + // determine whether to pick from an old bucket. + // if there's not enough old addresses to pick from, then we cant pick from old bucket. pickFromOldBucket := int((float64(selectionIndex)/float64(numAddresses))*100) >= biasTowardsNewAddrs - pickFromOldBucket = (pickFromOldBucket && a.nOld > 0) || a.nNew == 0 + pickFromOldBucket = (pickFromOldBucket && a.nOld > 0 && len(oldBucketToAddrsMap) < a.nOld) || a.nNew == 0 + bucket := make(map[string]*knownAddress) // loop until we pick a random non-empty bucket