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