github.com/DFWallet/tendermint-cosmos@v0.0.2/p2p/pex/known_address.go (about) 1 package pex 2 3 import ( 4 "time" 5 6 "github.com/DFWallet/tendermint-cosmos/p2p" 7 ) 8 9 // knownAddress tracks information about a known network address 10 // that is used to determine how viable an address is. 11 type knownAddress struct { 12 Addr *p2p.NetAddress `json:"addr"` 13 Src *p2p.NetAddress `json:"src"` 14 Buckets []int `json:"buckets"` 15 Attempts int32 `json:"attempts"` 16 BucketType byte `json:"bucket_type"` 17 LastAttempt time.Time `json:"last_attempt"` 18 LastSuccess time.Time `json:"last_success"` 19 LastBanTime time.Time `json:"last_ban_time"` 20 } 21 22 func newKnownAddress(addr *p2p.NetAddress, src *p2p.NetAddress) *knownAddress { 23 return &knownAddress{ 24 Addr: addr, 25 Src: src, 26 Attempts: 0, 27 LastAttempt: time.Now(), 28 BucketType: bucketTypeNew, 29 Buckets: nil, 30 } 31 } 32 33 func (ka *knownAddress) ID() p2p.ID { 34 return ka.Addr.ID 35 } 36 37 func (ka *knownAddress) isOld() bool { 38 return ka.BucketType == bucketTypeOld 39 } 40 41 func (ka *knownAddress) isNew() bool { 42 return ka.BucketType == bucketTypeNew 43 } 44 45 func (ka *knownAddress) markAttempt() { 46 now := time.Now() 47 ka.LastAttempt = now 48 ka.Attempts++ 49 } 50 51 func (ka *knownAddress) markGood() { 52 now := time.Now() 53 ka.LastAttempt = now 54 ka.Attempts = 0 55 ka.LastSuccess = now 56 } 57 58 func (ka *knownAddress) ban(banTime time.Duration) { 59 if ka.LastBanTime.Before(time.Now().Add(banTime)) { 60 ka.LastBanTime = time.Now().Add(banTime) 61 } 62 } 63 64 func (ka *knownAddress) isBanned() bool { 65 return ka.LastBanTime.After(time.Now()) 66 } 67 68 func (ka *knownAddress) addBucketRef(bucketIdx int) int { 69 for _, bucket := range ka.Buckets { 70 if bucket == bucketIdx { 71 // TODO refactor to return error? 72 // log.Warn(Fmt("Bucket already exists in ka.Buckets: %v", ka)) 73 return -1 74 } 75 } 76 ka.Buckets = append(ka.Buckets, bucketIdx) 77 return len(ka.Buckets) 78 } 79 80 func (ka *knownAddress) removeBucketRef(bucketIdx int) int { 81 buckets := []int{} 82 for _, bucket := range ka.Buckets { 83 if bucket != bucketIdx { 84 buckets = append(buckets, bucket) 85 } 86 } 87 if len(buckets) != len(ka.Buckets)-1 { 88 // TODO refactor to return error? 89 // log.Warn(Fmt("bucketIdx not found in ka.Buckets: %v", ka)) 90 return -1 91 } 92 ka.Buckets = buckets 93 return len(ka.Buckets) 94 } 95 96 /* 97 An address is bad if the address in question is a New address, has not been tried in the last 98 minute, and meets one of the following criteria: 99 100 1) It claims to be from the future 101 2) It hasn't been seen in over a week 102 3) It has failed at least three times and never succeeded 103 4) It has failed ten times in the last week 104 105 All addresses that meet these criteria are assumed to be worthless and not 106 worth keeping hold of. 107 108 */ 109 func (ka *knownAddress) isBad() bool { 110 // Is Old --> good 111 if ka.BucketType == bucketTypeOld { 112 return false 113 } 114 115 // Has been attempted in the last minute --> good 116 if ka.LastAttempt.After(time.Now().Add(-1 * time.Minute)) { 117 return false 118 } 119 120 // TODO: From the future? 121 122 // Too old? 123 // TODO: should be a timestamp of last seen, not just last attempt 124 if ka.LastAttempt.Before(time.Now().Add(-1 * numMissingDays * time.Hour * 24)) { 125 return true 126 } 127 128 // Never succeeded? 129 if ka.LastSuccess.IsZero() && ka.Attempts >= numRetries { 130 return true 131 } 132 133 // Hasn't succeeded in too long? 134 if ka.LastSuccess.Before(time.Now().Add(-1*minBadDays*time.Hour*24)) && 135 ka.Attempts >= maxFailures { 136 return true 137 } 138 139 return false 140 }