github.com/annchain/OG@v0.0.9/p2p/discover/table_util_test.go (about) 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 17 package discover 18 19 import ( 20 "crypto/ecdsa" 21 "encoding/hex" 22 "fmt" 23 "math/rand" 24 "net" 25 "sync" 26 27 "github.com/annchain/OG/p2p/enr" 28 "github.com/annchain/OG/p2p/onode" 29 ) 30 31 var nullNode *onode.Node 32 33 func init() { 34 var r enr.Record 35 ip := enr.IP{0, 0, 0, 0} 36 r.Set(&ip) 37 nullNode = onode.SignNull(&r, onode.ID{}) 38 } 39 40 func newTestTable(t transport) (*Table, *onode.DB) { 41 db, _ := onode.OpenDB("") 42 tab, _ := newTable(t, db, nil) 43 return tab, db 44 } 45 46 // nodeAtDistance creates a node for which onode.LogDist(base, n.id) == ld. 47 func nodeAtDistance(base onode.ID, ld int, ip net.IP) *node { 48 var r enr.Record 49 eIP := enr.IP(ip) 50 r.Set(&eIP) 51 return wrapNode(onode.SignNull(&r, idAtDistance(base, ld))) 52 } 53 54 // idAtDistance returns a random hash such that onode.LogDist(a, b) == n 55 func idAtDistance(a onode.ID, n int) (b onode.ID) { 56 if n == 0 { 57 return a 58 } 59 // flip bit at position n, fill the rest with random bits 60 b = a 61 pos := len(a) - n/8 - 1 62 bit := byte(0x01) << (byte(n%8) - 1) 63 if bit == 0 { 64 pos++ 65 bit = 0x80 66 } 67 b[pos] = a[pos]&^bit | ^a[pos]&bit // TODO: randomize end bits 68 for i := pos + 1; i < len(a); i++ { 69 b[i] = byte(rand.Intn(255)) 70 } 71 return b 72 } 73 74 func intIP(i int) net.IP { 75 return net.IP{byte(i), 0, 2, byte(i)} 76 } 77 78 // fillBucket inserts nodes into the given bucket until it is full. 79 func fillBucket(tab *Table, n *node) (last *node) { 80 ld := onode.LogDist(tab.self().ID(), n.ID()) 81 b := tab.bucket(n.ID()) 82 for len(b.entries) < bucketSize { 83 b.entries = append(b.entries, nodeAtDistance(tab.self().ID(), ld, intIP(ld))) 84 } 85 return b.entries[bucketSize-1] 86 } 87 88 type pingRecorder struct { 89 mu sync.Mutex 90 dead, pinged map[onode.ID]bool 91 n *onode.Node 92 } 93 94 func newPingRecorder() *pingRecorder { 95 var r enr.Record 96 eIp := enr.IP{0, 0, 0, 0} 97 r.Set(&eIp) 98 n := onode.SignNull(&r, onode.ID{}) 99 100 return &pingRecorder{ 101 dead: make(map[onode.ID]bool), 102 pinged: make(map[onode.ID]bool), 103 n: n, 104 } 105 } 106 107 func (t *pingRecorder) self() *onode.Node { 108 return nullNode 109 } 110 111 func (t *pingRecorder) findnode(toid onode.ID, toaddr *net.UDPAddr, target EncPubkey) ([]*node, error) { 112 return nil, nil 113 } 114 115 func (t *pingRecorder) waitping(from onode.ID) error { 116 return nil // remote always pings 117 } 118 119 func (t *pingRecorder) ping(toid onode.ID, toaddr *net.UDPAddr) error { 120 t.mu.Lock() 121 defer t.mu.Unlock() 122 123 t.pinged[toid] = true 124 if t.dead[toid] { 125 return errTimeout 126 } else { 127 return nil 128 } 129 } 130 131 func (t *pingRecorder) close() {} 132 133 func hasDuplicates(slice []*node) bool { 134 seen := make(map[onode.ID]bool) 135 for i, e := range slice { 136 if e == nil { 137 panic(fmt.Sprintf("nil *Node at %d", i)) 138 } 139 if seen[e.ID()] { 140 return true 141 } 142 seen[e.ID()] = true 143 } 144 return false 145 } 146 147 func contains(ns []*node, id onode.ID) bool { 148 for _, n := range ns { 149 if n.ID() == id { 150 return true 151 } 152 } 153 return false 154 } 155 156 func sortedByDistanceTo(distbase onode.ID, slice []*node) bool { 157 var last onode.ID 158 for i, e := range slice { 159 if i > 0 && onode.DistCmp(distbase, e.ID(), last) < 0 { 160 return false 161 } 162 last = e.ID() 163 } 164 return true 165 } 166 167 func hexEncPubkey(h string) (ret EncPubkey) { 168 b, err := hex.DecodeString(h) 169 if err != nil { 170 panic(err) 171 } 172 if len(b) != len(ret) { 173 panic("invalid length") 174 } 175 copy(ret[:], b) 176 return ret 177 } 178 179 func hexPubkey(h string) *ecdsa.PublicKey { 180 k, err := decodePubkey(hexEncPubkey(h)) 181 if err != nil { 182 panic(err) 183 } 184 return k 185 }