table_util_test.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. // Copyright 2015 The go-ethereum Authors
  2. // This file is part of the go-ethereum library.
  3. //
  4. // The go-ethereum library is free software: you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation, either version 3 of the License, or
  7. // (at your option) any later version.
  8. //
  9. // The go-ethereum library is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. // GNU Lesser General Public License for more details.
  13. //
  14. // You should have received a copy of the GNU Lesser General Public License
  15. // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
  16. package discover
  17. import (
  18. "crypto/ecdsa"
  19. "encoding/hex"
  20. "fmt"
  21. "math/rand"
  22. "net"
  23. "sync"
  24. "github.com/ethereum/go-ethereum/p2p/enode"
  25. "github.com/ethereum/go-ethereum/p2p/enr"
  26. )
  27. var nullNode *enode.Node
  28. func init() {
  29. var r enr.Record
  30. r.Set(enr.IP{0, 0, 0, 0})
  31. nullNode = enode.SignNull(&r, enode.ID{})
  32. }
  33. func newTestTable(t transport) (*Table, *enode.DB) {
  34. db, _ := enode.OpenDB("")
  35. tab, _ := newTable(t, db, nil)
  36. return tab, db
  37. }
  38. // nodeAtDistance creates a node for which enode.LogDist(base, n.id) == ld.
  39. func nodeAtDistance(base enode.ID, ld int, ip net.IP) *node {
  40. var r enr.Record
  41. r.Set(enr.IP(ip))
  42. return wrapNode(enode.SignNull(&r, idAtDistance(base, ld)))
  43. }
  44. // idAtDistance returns a random hash such that enode.LogDist(a, b) == n
  45. func idAtDistance(a enode.ID, n int) (b enode.ID) {
  46. if n == 0 {
  47. return a
  48. }
  49. // flip bit at position n, fill the rest with random bits
  50. b = a
  51. pos := len(a) - n/8 - 1
  52. bit := byte(0x01) << (byte(n%8) - 1)
  53. if bit == 0 {
  54. pos++
  55. bit = 0x80
  56. }
  57. b[pos] = a[pos]&^bit | ^a[pos]&bit // TODO: randomize end bits
  58. for i := pos + 1; i < len(a); i++ {
  59. b[i] = byte(rand.Intn(255))
  60. }
  61. return b
  62. }
  63. func intIP(i int) net.IP {
  64. return net.IP{byte(i), 0, 2, byte(i)}
  65. }
  66. // fillBucket inserts nodes into the given bucket until it is full.
  67. func fillBucket(tab *Table, n *node) (last *node) {
  68. ld := enode.LogDist(tab.self().ID(), n.ID())
  69. b := tab.bucket(n.ID())
  70. for len(b.entries) < bucketSize {
  71. b.entries = append(b.entries, nodeAtDistance(tab.self().ID(), ld, intIP(ld)))
  72. }
  73. return b.entries[bucketSize-1]
  74. }
  75. type pingRecorder struct {
  76. mu sync.Mutex
  77. dead, pinged map[enode.ID]bool
  78. n *enode.Node
  79. }
  80. func newPingRecorder() *pingRecorder {
  81. var r enr.Record
  82. r.Set(enr.IP{0, 0, 0, 0})
  83. n := enode.SignNull(&r, enode.ID{})
  84. return &pingRecorder{
  85. dead: make(map[enode.ID]bool),
  86. pinged: make(map[enode.ID]bool),
  87. n: n,
  88. }
  89. }
  90. func (t *pingRecorder) self() *enode.Node {
  91. return nullNode
  92. }
  93. func (t *pingRecorder) findnode(toid enode.ID, toaddr *net.UDPAddr, target encPubkey) ([]*node, error) {
  94. return nil, nil
  95. }
  96. func (t *pingRecorder) waitping(from enode.ID) error {
  97. return nil // remote always pings
  98. }
  99. func (t *pingRecorder) ping(toid enode.ID, toaddr *net.UDPAddr) error {
  100. t.mu.Lock()
  101. defer t.mu.Unlock()
  102. t.pinged[toid] = true
  103. if t.dead[toid] {
  104. return errTimeout
  105. } else {
  106. return nil
  107. }
  108. }
  109. func (t *pingRecorder) close() {}
  110. func hasDuplicates(slice []*node) bool {
  111. seen := make(map[enode.ID]bool)
  112. for i, e := range slice {
  113. if e == nil {
  114. panic(fmt.Sprintf("nil *Node at %d", i))
  115. }
  116. if seen[e.ID()] {
  117. return true
  118. }
  119. seen[e.ID()] = true
  120. }
  121. return false
  122. }
  123. func contains(ns []*node, id enode.ID) bool {
  124. for _, n := range ns {
  125. if n.ID() == id {
  126. return true
  127. }
  128. }
  129. return false
  130. }
  131. func sortedByDistanceTo(distbase enode.ID, slice []*node) bool {
  132. var last enode.ID
  133. for i, e := range slice {
  134. if i > 0 && enode.DistCmp(distbase, e.ID(), last) < 0 {
  135. return false
  136. }
  137. last = e.ID()
  138. }
  139. return true
  140. }
  141. func hexEncPubkey(h string) (ret encPubkey) {
  142. b, err := hex.DecodeString(h)
  143. if err != nil {
  144. panic(err)
  145. }
  146. if len(b) != len(ret) {
  147. panic("invalid length")
  148. }
  149. copy(ret[:], b)
  150. return ret
  151. }
  152. func hexPubkey(h string) *ecdsa.PublicKey {
  153. k, err := decodePubkey(hexEncPubkey(h))
  154. if err != nil {
  155. panic(err)
  156. }
  157. return k
  158. }