github.com/pure-x-eth/consensus_tm@v0.0.0-20230502163723-e3c2ff987250/p2p/pex/known_address.go (about) 1 package pex 2 3 import ( 4 "time" 5 6 "github.com/pure-x-eth/consensus_tm/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 func (ka *knownAddress) isBad() bool { 109 // Is Old --> good 110 if ka.BucketType == bucketTypeOld { 111 return false 112 } 113 114 // Has been attempted in the last minute --> good 115 if ka.LastAttempt.After(time.Now().Add(-1 * time.Minute)) { 116 return false 117 } 118 119 // TODO: From the future? 120 121 // Too old? 122 // TODO: should be a timestamp of last seen, not just last attempt 123 if ka.LastAttempt.Before(time.Now().Add(-1 * numMissingDays * time.Hour * 24)) { 124 return true 125 } 126 127 // Never succeeded? 128 if ka.LastSuccess.IsZero() && ka.Attempts >= numRetries { 129 return true 130 } 131 132 // Hasn't succeeded in too long? 133 if ka.LastSuccess.Before(time.Now().Add(-1*minBadDays*time.Hour*24)) && 134 ka.Attempts >= maxFailures { 135 return true 136 } 137 138 return false 139 }