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 }