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  }