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