github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/p2p/discover/node_test.go (about)

     1  
     2  //此源码被清华学神尹成大魔王专业翻译分析并修改
     3  //尹成QQ77025077
     4  //尹成微信18510341407
     5  //尹成所在QQ群721929980
     6  //尹成邮箱 yinc13@mails.tsinghua.edu.cn
     7  //尹成毕业于清华大学,微软区块链领域全球最有价值专家
     8  //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620
     9  //版权所有2015 Go Ethereum作者
    10  //此文件是Go以太坊库的一部分。
    11  //
    12  //Go-Ethereum库是免费软件:您可以重新分发它和/或修改
    13  //根据GNU发布的较低通用公共许可证的条款
    14  //自由软件基金会,或者许可证的第3版,或者
    15  //(由您选择)任何更高版本。
    16  //
    17  //Go以太坊图书馆的发行目的是希望它会有用,
    18  //但没有任何保证;甚至没有
    19  //适销性或特定用途的适用性。见
    20  //GNU较低的通用公共许可证,了解更多详细信息。
    21  //
    22  //你应该收到一份GNU较低级别的公共许可证副本
    23  //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。
    24  
    25  package discover
    26  
    27  import (
    28  	"bytes"
    29  	"fmt"
    30  	"math/big"
    31  	"math/rand"
    32  	"net"
    33  	"reflect"
    34  	"strings"
    35  	"testing"
    36  	"testing/quick"
    37  	"time"
    38  
    39  	"github.com/ethereum/go-ethereum/common"
    40  	"github.com/ethereum/go-ethereum/crypto"
    41  )
    42  
    43  func ExampleNewNode() {
    44  	id := MustHexID("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439")
    45  
    46  //完整节点包含UDP和TCP终结点:
    47  	n1 := NewNode(id, net.ParseIP("2001:db8:3c4d:15::abcd:ef12"), 52150, 30303)
    48  	fmt.Println("n1:", n1)
    49  	fmt.Println("n1.Incomplete() ->", n1.Incomplete())
    50  
    51  //通过传递零值可以创建不完整的节点
    52  //用于除ID以外的所有参数。
    53  	n2 := NewNode(id, nil, 0, 0)
    54  	fmt.Println("n2:", n2)
    55  	fmt.Println("n2.Incomplete() ->", n2.Incomplete())
    56  
    57  //输出:
    58  //n1:enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6c1c64a5c8d659f51fcd512be2435232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@[2001:db8:3c4d:15::abcd:ef12]:30303?磁盘端口=52150
    59  //n1.incomplete()->错误
    60  //n2:enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6c1c64a5c8d659f51fcd512be2435232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439
    61  //n2.incomplete()->真
    62  }
    63  
    64  var parseNodeTests = []struct {
    65  	rawurl     string
    66  	wantError  string
    67  	wantResult *Node
    68  }{
    69  	{
    70  rawurl:    "http://“福巴”
    71  		wantError: `invalid URL scheme, want "enode"`,
    72  	},
    73  	{
    74  rawurl:    "enode://01010101@123.124.125.126:3“,
    75  		wantError: `invalid node ID (wrong length, want 128 hex chars)`,
    76  	},
    77  //使用IP地址完成节点。
    78  	{
    79  rawurl:    "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6c1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@hostname:3“,
    80  		wantError: `invalid IP address`,
    81  	},
    82  	{
    83  rawurl:    "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6c1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@127.0.0.1:foo“,
    84  		wantError: `invalid port`,
    85  	},
    86  	{
    87  rawurl:    "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6c1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@127.0.0.1:3?迪斯科=
    88  		wantError: `invalid discport in query`,
    89  	},
    90  	{
    91  rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6c1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@127.0.0.1:52150“,
    92  		wantResult: NewNode(
    93  			MustHexID("0x1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
    94  			net.IP{0x7f, 0x0, 0x0, 0x1},
    95  			52150,
    96  			52150,
    97  		),
    98  	},
    99  	{
   100  rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6c1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@[::]:52150“,
   101  		wantResult: NewNode(
   102  			MustHexID("0x1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
   103  			net.ParseIP("::"),
   104  			52150,
   105  			52150,
   106  		),
   107  	},
   108  	{
   109  rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6c1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@[2001:db8:3c4d:15::abcd:ef12]:52150“,
   110  		wantResult: NewNode(
   111  			MustHexID("0x1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
   112  			net.ParseIP("2001:db8:3c4d:15::abcd:ef12"),
   113  			52150,
   114  			52150,
   115  		),
   116  	},
   117  	{
   118  rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6c1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@127.0.0.1:52150?discport=22334“,
   119  		wantResult: NewNode(
   120  			MustHexID("0x1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
   121  			net.IP{0x7f, 0x0, 0x0, 0x1},
   122  			22334,
   123  			52150,
   124  		),
   125  	},
   126  //没有地址的不完整节点。
   127  	{
   128  		rawurl: "1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439",
   129  		wantResult: NewNode(
   130  			MustHexID("0x1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
   131  			nil, 0, 0,
   132  		),
   133  	},
   134  	{
   135  rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6c6c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439“,
   136  		wantResult: NewNode(
   137  			MustHexID("0x1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"),
   138  			nil, 0, 0,
   139  		),
   140  	},
   141  //无效网址
   142  	{
   143  		rawurl:    "01010101",
   144  		wantError: `invalid node ID (wrong length, want 128 hex chars)`,
   145  	},
   146  	{
   147  rawurl:    "enode://01010101“,
   148  		wantError: `invalid node ID (wrong length, want 128 hex chars)`,
   149  	},
   150  	{
   151  //此测试检查是否处理了URL.Parse中的错误。
   152  rawurl:    "://“,”
   153  wantError: `parse ://foo:缺少协议方案`,
   154  	},
   155  }
   156  
   157  func TestParseNode(t *testing.T) {
   158  	for _, test := range parseNodeTests {
   159  		n, err := ParseNode(test.rawurl)
   160  		if test.wantError != "" {
   161  			if err == nil {
   162  				t.Errorf("test %q:\n  got nil error, expected %#q", test.rawurl, test.wantError)
   163  				continue
   164  			} else if err.Error() != test.wantError {
   165  				t.Errorf("test %q:\n  got error %#q, expected %#q", test.rawurl, err.Error(), test.wantError)
   166  				continue
   167  			}
   168  		} else {
   169  			if err != nil {
   170  				t.Errorf("test %q:\n  unexpected error: %v", test.rawurl, err)
   171  				continue
   172  			}
   173  			if !reflect.DeepEqual(n, test.wantResult) {
   174  				t.Errorf("test %q:\n  result mismatch:\ngot:  %#v, want: %#v", test.rawurl, n, test.wantResult)
   175  			}
   176  		}
   177  	}
   178  }
   179  
   180  func TestNodeString(t *testing.T) {
   181  	for i, test := range parseNodeTests {
   182  if test.wantError == "" && strings.HasPrefix(test.rawurl, "enode://“”{
   183  			str := test.wantResult.String()
   184  			if str != test.rawurl {
   185  				t.Errorf("test %d: Node.String() mismatch:\ngot:  %s\nwant: %s", i, str, test.rawurl)
   186  			}
   187  		}
   188  	}
   189  }
   190  
   191  func TestHexID(t *testing.T) {
   192  	ref := NodeID{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 106, 217, 182, 31, 165, 174, 1, 67, 7, 235, 220, 150, 66, 83, 173, 205, 159, 44, 10, 57, 42, 161, 26, 188}
   193  	id1 := MustHexID("0x000000000000000000000000000000000000000000000000000000000000000000000000000000806ad9b61fa5ae014307ebdc964253adcd9f2c0a392aa11abc")
   194  	id2 := MustHexID("000000000000000000000000000000000000000000000000000000000000000000000000000000806ad9b61fa5ae014307ebdc964253adcd9f2c0a392aa11abc")
   195  
   196  	if id1 != ref {
   197  		t.Errorf("wrong id1\ngot  %v\nwant %v", id1[:], ref[:])
   198  	}
   199  	if id2 != ref {
   200  		t.Errorf("wrong id2\ngot  %v\nwant %v", id2[:], ref[:])
   201  	}
   202  }
   203  
   204  func TestNodeID_textEncoding(t *testing.T) {
   205  	ref := NodeID{
   206  		0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10,
   207  		0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20,
   208  		0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30,
   209  		0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x40,
   210  		0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x50,
   211  		0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x60,
   212  		0x61, 0x62, 0x63, 0x64,
   213  	}
   214  	hex := "01020304050607080910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364"
   215  
   216  	text, err := ref.MarshalText()
   217  	if err != nil {
   218  		t.Fatal(err)
   219  	}
   220  	if !bytes.Equal(text, []byte(hex)) {
   221  		t.Fatalf("text encoding did not match\nexpected: %s\ngot:      %s", hex, text)
   222  	}
   223  
   224  	id := new(NodeID)
   225  	if err := id.UnmarshalText(text); err != nil {
   226  		t.Fatal(err)
   227  	}
   228  	if *id != ref {
   229  		t.Fatalf("text decoding did not match\nexpected: %s\ngot:      %s", ref, id)
   230  	}
   231  }
   232  
   233  func TestNodeID_recover(t *testing.T) {
   234  	prv := newkey()
   235  	hash := make([]byte, 32)
   236  	sig, err := crypto.Sign(hash, prv)
   237  	if err != nil {
   238  		t.Fatalf("signing error: %v", err)
   239  	}
   240  
   241  	pub := PubkeyID(&prv.PublicKey)
   242  	recpub, err := recoverNodeID(hash, sig)
   243  	if err != nil {
   244  		t.Fatalf("recovery error: %v", err)
   245  	}
   246  	if pub != recpub {
   247  		t.Errorf("recovered wrong pubkey:\ngot:  %v\nwant: %v", recpub, pub)
   248  	}
   249  
   250  	ecdsa, err := pub.Pubkey()
   251  	if err != nil {
   252  		t.Errorf("Pubkey error: %v", err)
   253  	}
   254  	if !reflect.DeepEqual(ecdsa, &prv.PublicKey) {
   255  		t.Errorf("Pubkey mismatch:\n  got:  %#v\n  want: %#v", ecdsa, &prv.PublicKey)
   256  	}
   257  }
   258  
   259  func TestNodeID_pubkeyBad(t *testing.T) {
   260  	ecdsa, err := NodeID{}.Pubkey()
   261  	if err == nil {
   262  		t.Error("expected error for zero ID")
   263  	}
   264  	if ecdsa != nil {
   265  		t.Error("expected nil result")
   266  	}
   267  }
   268  
   269  func TestNodeID_distcmp(t *testing.T) {
   270  	distcmpBig := func(target, a, b common.Hash) int {
   271  		tbig := new(big.Int).SetBytes(target[:])
   272  		abig := new(big.Int).SetBytes(a[:])
   273  		bbig := new(big.Int).SetBytes(b[:])
   274  		return new(big.Int).Xor(tbig, abig).Cmp(new(big.Int).Xor(tbig, bbig))
   275  	}
   276  	if err := quick.CheckEqual(distcmp, distcmpBig, quickcfg()); err != nil {
   277  		t.Error(err)
   278  	}
   279  }
   280  
   281  //随机测试很可能会错过它们相等的情况。
   282  func TestNodeID_distcmpEqual(t *testing.T) {
   283  	base := common.Hash{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
   284  	x := common.Hash{15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}
   285  	if distcmp(base, x, x) != 0 {
   286  		t.Errorf("distcmp(base, x, x) != 0")
   287  	}
   288  }
   289  
   290  func TestNodeID_logdist(t *testing.T) {
   291  	logdistBig := func(a, b common.Hash) int {
   292  		abig, bbig := new(big.Int).SetBytes(a[:]), new(big.Int).SetBytes(b[:])
   293  		return new(big.Int).Xor(abig, bbig).BitLen()
   294  	}
   295  	if err := quick.CheckEqual(logdist, logdistBig, quickcfg()); err != nil {
   296  		t.Error(err)
   297  	}
   298  }
   299  
   300  //随机测试很可能会错过它们相等的情况。
   301  func TestNodeID_logdistEqual(t *testing.T) {
   302  	x := common.Hash{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}
   303  	if logdist(x, x) != 0 {
   304  		t.Errorf("logdist(x, x) != 0")
   305  	}
   306  }
   307  
   308  func TestNodeID_hashAtDistance(t *testing.T) {
   309  //我们不使用quick。请检查这里,因为它的输出不是
   310  //当测试失败时非常有用。
   311  	cfg := quickcfg()
   312  	for i := 0; i < cfg.MaxCount; i++ {
   313  		a := gen(common.Hash{}, cfg.Rand).(common.Hash)
   314  		dist := cfg.Rand.Intn(len(common.Hash{}) * 8)
   315  		result := hashAtDistance(a, dist)
   316  		actualdist := logdist(result, a)
   317  
   318  		if dist != actualdist {
   319  			t.Log("a:     ", a)
   320  			t.Log("result:", result)
   321  			t.Fatalf("#%d: distance of result is %d, want %d", i, actualdist, dist)
   322  		}
   323  	}
   324  }
   325  
   326  func quickcfg() *quick.Config {
   327  	return &quick.Config{
   328  		MaxCount: 5000,
   329  		Rand:     rand.New(rand.NewSource(time.Now().Unix())),
   330  	}
   331  }
   332  
   333  //TODO:当我们需要go大于等于1.5时,可以删除generate方法。
   334  //因为测试/快速学习在1.5中生成数组。
   335  
   336  func (NodeID) Generate(rand *rand.Rand, size int) reflect.Value {
   337  	var id NodeID
   338  	m := rand.Intn(len(id))
   339  	for i := len(id) - 1; i > m; i-- {
   340  		id[i] = byte(rand.Uint32())
   341  	}
   342  	return reflect.ValueOf(id)
   343  }