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  }