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