func (r *PEXReactor) ensurePeers() {
	numOutPeers, _, numDialing := r.Switch.NumPeers()
	numToDial := minNumOutboundPeers - (numOutPeers + numDialing)
	log.Info("Ensure peers", "numOutPeers", numOutPeers, "numDialing", numDialing, "numToDial", numToDial)
	if numToDial <= 0 {
		return
	}

	toDial := make(map[string]*NetAddress)

	// Try to pick numToDial addresses to dial.
	for i := 0; i < numToDial; i++ {
		// The purpose of newBias is to first prioritize old (more vetted) peers
		// when we have few connections, but to allow for new (less vetted) peers
		// if we already have many connections. This algorithm isn't perfect, but
		// it somewhat ensures that we prioritize connecting to more-vetted
		// peers.
		newBias := cmn.MinInt(numOutPeers, 8)*10 + 10
		var picked *NetAddress
		// Try to fetch a new peer 3 times.
		// This caps the maximum number of tries to 3 * numToDial.
		for j := 0; j < 3; j++ {
			try := r.book.PickAddress(newBias)
			if try == nil {
				break
			}
			_, alreadySelected := toDial[try.IP.String()]
			alreadyDialing := r.Switch.IsDialing(try)
			alreadyConnected := r.Switch.Peers().Has(try.IP.String())
			if alreadySelected || alreadyDialing || alreadyConnected {
				// log.Info("Cannot dial address", "addr", try,
				// 	"alreadySelected", alreadySelected,
				// 	"alreadyDialing", alreadyDialing,
				//  "alreadyConnected", alreadyConnected)
				continue
			} else {
				log.Info("Will dial address", "addr", try)
				picked = try
				break
			}
		}
		if picked == nil {
			continue
		}
		toDial[picked.IP.String()] = picked
	}

	// Dial picked addresses
	for _, item := range toDial {
		go func(picked *NetAddress) {
			_, err := r.Switch.DialPeerWithAddress(picked, false)
			if err != nil {
				r.book.MarkAttempt(picked)
			}
		}(item)
	}

	// If we need more addresses, pick a random peer and ask for more.
	if r.book.NeedMoreAddrs() {
		if peers := r.Switch.Peers().List(); len(peers) > 0 {
			i := rand.Int() % len(peers)
			peer := peers[i]
			log.Info("No addresses to dial. Sending pexRequest to random peer", "peer", peer)
			r.RequestPEX(peer)
		}
	}
}
func (r *PEXReactor) ensurePeers() {
	numOutPeers, _, numDialing := r.Switch.NumPeers()
	numToDial := minNumOutboundPeers - (numOutPeers + numDialing)
	log.Info("Ensure peers", "numOutPeers", numOutPeers, "numDialing", numDialing, "numToDial", numToDial)
	if numToDial <= 0 {
		return
	}

	toDial := make(map[string]*NetAddress)

	
	for i := 0; i < numToDial; i++ {
		
		
		
		
		
		newBias := cmn.MinInt(numOutPeers, 8)*10 + 10
		var picked *NetAddress
		
		
		for j := 0; j < 3; j++ {
			try := r.book.PickAddress(newBias)
			if try == nil {
				break
			}
			_, alreadySelected := toDial[try.IP.String()]
			alreadyDialing := r.Switch.IsDialing(try)
			alreadyConnected := r.Switch.Peers().Has(try.IP.String())
			if alreadySelected || alreadyDialing || alreadyConnected {
				
				
				
				
				continue
			} else {
				log.Info("Will dial address", "addr", try)
				picked = try
				break
			}
		}
		if picked == nil {
			continue
		}
		toDial[picked.IP.String()] = picked
	}

	
	for _, item := range toDial {
		go func(picked *NetAddress) {
			_, err := r.Switch.DialPeerWithAddress(picked, false)
			if err != nil {
				r.book.MarkAttempt(picked)
			}
		}(item)
	}

	
	if r.book.NeedMoreAddrs() {
		if peers := r.Switch.Peers().List(); len(peers) > 0 {
			i := rand.Int() % len(peers)
			peer := peers[i]
			log.Info("No addresses to dial. Sending pexRequest to random peer", "peer", peer)
			r.RequestPEX(peer)
		}
	}
}
func ( r * PEXReactor ) ensurePeers ( ) { numOutPeers , _ , numDialing := r . Switch . NumPeers ( ) numToDial := minNumOutboundPeers - ( numOutPeers + numDialing ) log . Info ( " " , " " , numOutPeers , " " , numDialing , " " , numToDial ) if numToDial <= 0 { return } toDial := make ( map [ string ] * NetAddress ) // Try to pick numToDial addresses to dial. for i := 0 ; i < numToDial ; i ++ { // The purpose of newBias is to first prioritize old (more vetted) peers // when we have few connections, but to allow for new (less vetted) peers // if we already have many connections. This algorithm isn't perfect, but // it somewhat ensures that we prioritize connecting to more-vetted // peers. newBias := cmn . MinInt ( numOutPeers , 8 ) * 10 + 10 var picked * NetAddress // Try to fetch a new peer 3 times. // This caps the maximum number of tries to 3 * numToDial. for j := 0 ; j < 3 ; j ++ { try := r . book . PickAddress ( newBias ) if try == nil { break } _ , alreadySelected := toDial [ try . IP . String ( ) ] alreadyDialing := r . Switch . IsDialing ( try ) alreadyConnected := r . Switch . Peers ( ) . Has ( try . IP . String ( ) ) if alreadySelected || alreadyDialing || alreadyConnected { // log.Info("Cannot dial address", "addr", try, // 	"alreadySelected", alreadySelected, // 	"alreadyDialing", alreadyDialing, //  "alreadyConnected", alreadyConnected) continue } else { log . Info ( " " , " " , try ) picked = try break } } if picked == nil { continue } toDial [ picked . IP . String ( ) ] = picked } // Dial picked addresses for _ , item := range toDial { go func ( picked * NetAddress ) { _ , err := r . Switch . DialPeerWithAddress ( picked , false ) if err != nil { r . book . MarkAttempt ( picked ) } } ( item ) } // If we need more addresses, pick a random peer and ask for more. if r . book . NeedMoreAddrs ( ) { if peers := r . Switch . Peers ( ) . List ( ) ; len ( peers ) > 0 { i := rand . Int ( ) % len ( peers ) peer := peers [ i ] log . Info ( " " , " " , peer ) r . RequestPEX ( peer ) } } }
// ensurePeers ensures that sufficient peers are connected. (once)
//
// Old bucket / New bucket are arbitrary categories to denote whether an
// address is vetted or not, and this needs to be determined over time via a
// heuristic that we haven't perfected yet, or, perhaps is manually edited by
// the node operator. It should not be used to compute what addresses are
// already connected or not.
//
// TODO Basically, we need to work harder on our good-peer/bad-peer marking.
// What we're currently doing in terms of marking good/bad peers is just a
// placeholder. It should not be the case that an address becomes old/vetted
// upon a single successful connection.
ensurePeers ensures that sufficient peers are connected . ( once ) Old bucket / New bucket are arbitrary categories to denote whether an address is vetted or not and this needs to be determined over time via a heuristic that we haven t perfected yet or perhaps is manually edited by the node operator . It should not be used to compute what addresses are already connected or not . TODO Basically we need to work harder on our good - peer / bad - peer marking . What we re currently doing in terms of marking good / bad peers is just a placeholder . It should not be the case that an address becomes old / vetted upon a single successful connection .