You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

104 lines
2.8 KiB

10 years ago
10 years ago
10 years ago
  1. package peer
  2. import (
  3. . "github.com/tendermint/tendermint/binary"
  4. "time"
  5. "io"
  6. )
  7. /*
  8. KnownAddress
  9. tracks information about a known network address that is used
  10. to determine how viable an address is.
  11. */
  12. type KnownAddress struct {
  13. Addr *NetAddress
  14. Src *NetAddress
  15. Attempts UInt32
  16. LastAttempt Time
  17. LastSuccess Time
  18. NewRefs UInt16
  19. OldBucket Int16 // TODO init to -1
  20. }
  21. func NewKnownAddress(addr *NetAddress, src *NetAddress) *KnownAddress {
  22. return &KnownAddress{
  23. Addr: addr,
  24. Src: src,
  25. OldBucket: -1,
  26. LastAttempt: Time{time.Now()},
  27. Attempts: 0,
  28. }
  29. }
  30. func ReadKnownAddress(r io.Reader) *KnownAddress {
  31. return &KnownAddress{
  32. Addr: ReadNetAddress(r),
  33. Src: ReadNetAddress(r),
  34. Attempts: ReadUInt32(r),
  35. LastAttempt: ReadTime(r),
  36. LastSuccess: ReadTime(r),
  37. NewRefs: ReadUInt16(r),
  38. OldBucket: ReadInt16(r),
  39. }
  40. }
  41. func (ka *KnownAddress) WriteTo(w io.Writer) (n int64, err error) {
  42. n, err = WriteOnto(ka.Addr, w, n, err)
  43. n, err = WriteOnto(ka.Src, w, n, err)
  44. n, err = WriteOnto(ka.Attempts, w, n, err)
  45. n, err = WriteOnto(ka.LastAttempt, w, n, err)
  46. n, err = WriteOnto(ka.LastSuccess, w, n, err)
  47. n, err = WriteOnto(ka.NewRefs, w, n, err)
  48. n, err = WriteOnto(ka.OldBucket, w, n, err)
  49. return
  50. }
  51. func (ka *KnownAddress) MarkAttempt(success bool) {
  52. now := Time{time.Now()}
  53. ka.LastAttempt = now
  54. if success {
  55. ka.LastSuccess = now
  56. ka.Attempts = 0
  57. } else {
  58. ka.Attempts += 1
  59. }
  60. }
  61. /*
  62. An address is bad if the address in question has not been tried in the last
  63. minute and meets one of the following criteria:
  64. 1) It claims to be from the future
  65. 2) It hasn't been seen in over a month
  66. 3) It has failed at least three times and never succeeded
  67. 4) It has failed ten times in the last week
  68. All addresses that meet these criteria are assumed to be worthless and not
  69. worth keeping hold of.
  70. */
  71. func (ka *KnownAddress) Bad() bool {
  72. // Has been attempted in the last minute --> good
  73. if ka.LastAttempt.Before(time.Now().Add(-1 * time.Minute)) {
  74. return false
  75. }
  76. // Over a month old?
  77. if ka.LastAttempt.After(time.Now().Add(-1 * numMissingDays * time.Hour * 24)) {
  78. return true
  79. }
  80. // Never succeeded?
  81. if ka.LastSuccess.IsZero() && ka.Attempts >= numRetries {
  82. return true
  83. }
  84. // Hasn't succeeded in too long?
  85. if ka.LastSuccess.Before(time.Now().Add(-1*minBadDays*time.Hour*24)) &&
  86. ka.Attempts >= maxFailures {
  87. return true
  88. }
  89. return false
  90. }