package peer
|
|
|
|
import (
|
|
. "github.com/tendermint/tendermint/binary"
|
|
"time"
|
|
"io"
|
|
)
|
|
|
|
/*
|
|
KnownAddress
|
|
|
|
tracks information about a known network address that is used
|
|
to determine how viable an address is.
|
|
*/
|
|
type KnownAddress struct {
|
|
Addr *NetAddress
|
|
Src *NetAddress
|
|
Attempts UInt32
|
|
LastAttempt Time
|
|
LastSuccess Time
|
|
NewRefs UInt16
|
|
OldBucket Int16 // TODO init to -1
|
|
}
|
|
|
|
func NewKnownAddress(addr *NetAddress, src *NetAddress) *KnownAddress {
|
|
return &KnownAddress{
|
|
Addr: addr,
|
|
Src: src,
|
|
OldBucket: -1,
|
|
LastAttempt: Time{time.Now()},
|
|
Attempts: 0,
|
|
}
|
|
}
|
|
|
|
func ReadKnownAddress(r io.Reader) *KnownAddress {
|
|
return &KnownAddress{
|
|
Addr: ReadNetAddress(r),
|
|
Src: ReadNetAddress(r),
|
|
Attempts: ReadUInt32(r),
|
|
LastAttempt: ReadTime(r),
|
|
LastSuccess: ReadTime(r),
|
|
NewRefs: ReadUInt16(r),
|
|
OldBucket: ReadInt16(r),
|
|
}
|
|
}
|
|
|
|
func (ka *KnownAddress) WriteTo(w io.Writer) (n int64, err error) {
|
|
n, err = WriteOnto(ka.Addr, w, n, err)
|
|
n, err = WriteOnto(ka.Src, w, n, err)
|
|
n, err = WriteOnto(ka.Attempts, w, n, err)
|
|
n, err = WriteOnto(ka.LastAttempt, w, n, err)
|
|
n, err = WriteOnto(ka.LastSuccess, w, n, err)
|
|
n, err = WriteOnto(ka.NewRefs, w, n, err)
|
|
n, err = WriteOnto(ka.OldBucket, w, n, err)
|
|
return
|
|
}
|
|
|
|
func (ka *KnownAddress) MarkAttempt(success bool) {
|
|
now := Time{time.Now()}
|
|
ka.LastAttempt = now
|
|
if success {
|
|
ka.LastSuccess = now
|
|
ka.Attempts = 0
|
|
} else {
|
|
ka.Attempts += 1
|
|
}
|
|
}
|
|
|
|
/*
|
|
An address is bad if the address in question has not been tried in the last
|
|
minute and meets one of the following criteria:
|
|
|
|
1) It claims to be from the future
|
|
2) It hasn't been seen in over a month
|
|
3) It has failed at least three times and never succeeded
|
|
4) It has failed ten times in the last week
|
|
|
|
All addresses that meet these criteria are assumed to be worthless and not
|
|
worth keeping hold of.
|
|
*/
|
|
func (ka *KnownAddress) Bad() bool {
|
|
// Has been attempted in the last minute --> good
|
|
if ka.LastAttempt.Before(time.Now().Add(-1 * time.Minute)) {
|
|
return false
|
|
}
|
|
|
|
// Over a month old?
|
|
if ka.LastAttempt.After(time.Now().Add(-1 * numMissingDays * time.Hour * 24)) {
|
|
return true
|
|
}
|
|
|
|
// Never succeeded?
|
|
if ka.LastSuccess.IsZero() && ka.Attempts >= numRetries {
|
|
return true
|
|
}
|
|
|
|
// Hasn't succeeded in too long?
|
|
if ka.LastSuccess.Before(time.Now().Add(-1*minBadDays*time.Hour*24)) &&
|
|
ka.Attempts >= maxFailures {
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|