github.com/palcoin-project/palcd@v1.0.0/addrmgr/knownaddress.go (about)

     1  // Copyright (c) 2013-2014 The btcsuite developers
     2  // Use of this source code is governed by an ISC
     3  // license that can be found in the LICENSE file.
     4  
     5  package addrmgr
     6  
     7  import (
     8  	"time"
     9  
    10  	"github.com/palcoin-project/palcd/wire"
    11  )
    12  
    13  // KnownAddress tracks information about a known network address that is used
    14  // to determine how viable an address is.
    15  type KnownAddress struct {
    16  	na          *wire.NetAddress
    17  	srcAddr     *wire.NetAddress
    18  	attempts    int
    19  	lastattempt time.Time
    20  	lastsuccess time.Time
    21  	tried       bool
    22  	refs        int // reference count of new buckets
    23  }
    24  
    25  // NetAddress returns the underlying wire.NetAddress associated with the
    26  // known address.
    27  func (ka *KnownAddress) NetAddress() *wire.NetAddress {
    28  	return ka.na
    29  }
    30  
    31  // LastAttempt returns the last time the known address was attempted.
    32  func (ka *KnownAddress) LastAttempt() time.Time {
    33  	return ka.lastattempt
    34  }
    35  
    36  // Services returns the services supported by the peer with the known address.
    37  func (ka *KnownAddress) Services() wire.ServiceFlag {
    38  	return ka.na.Services
    39  }
    40  
    41  // chance returns the selection probability for a known address.  The priority
    42  // depends upon how recently the address has been seen, how recently it was last
    43  // attempted and how often attempts to connect to it have failed.
    44  func (ka *KnownAddress) chance() float64 {
    45  	now := time.Now()
    46  	lastAttempt := now.Sub(ka.lastattempt)
    47  
    48  	if lastAttempt < 0 {
    49  		lastAttempt = 0
    50  	}
    51  
    52  	c := 1.0
    53  
    54  	// Very recent attempts are less likely to be retried.
    55  	if lastAttempt < 10*time.Minute {
    56  		c *= 0.01
    57  	}
    58  
    59  	// Failed attempts deprioritise.
    60  	for i := ka.attempts; i > 0; i-- {
    61  		c /= 1.5
    62  	}
    63  
    64  	return c
    65  }
    66  
    67  // isBad returns true if the address in question has not been tried in the last
    68  // minute and meets one of the following criteria:
    69  // 1) It claims to be from the future
    70  // 2) It hasn't been seen in over a month
    71  // 3) It has failed at least three times and never succeeded
    72  // 4) It has failed ten times in the last week
    73  // All addresses that meet these criteria are assumed to be worthless and not
    74  // worth keeping hold of.
    75  func (ka *KnownAddress) isBad() bool {
    76  	if ka.lastattempt.After(time.Now().Add(-1 * time.Minute)) {
    77  		return false
    78  	}
    79  
    80  	// From the future?
    81  	if ka.na.Timestamp.After(time.Now().Add(10 * time.Minute)) {
    82  		return true
    83  	}
    84  
    85  	// Over a month old?
    86  	if ka.na.Timestamp.Before(time.Now().Add(-1 * numMissingDays * time.Hour * 24)) {
    87  		return true
    88  	}
    89  
    90  	// Never succeeded?
    91  	if ka.lastsuccess.IsZero() && ka.attempts >= numRetries {
    92  		return true
    93  	}
    94  
    95  	// Hasn't succeeded in too long?
    96  	if !ka.lastsuccess.After(time.Now().Add(-1*minBadDays*time.Hour*24)) &&
    97  		ka.attempts >= maxFailures {
    98  		return true
    99  	}
   100  
   101  	return false
   102  }