github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/p2p/enr/enr_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  //版权所有2017 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 enr
    26  
    27  import (
    28  	"bytes"
    29  	"encoding/hex"
    30  	"fmt"
    31  	"math/rand"
    32  	"testing"
    33  	"time"
    34  
    35  	"github.com/ethereum/go-ethereum/crypto"
    36  	"github.com/ethereum/go-ethereum/rlp"
    37  	"github.com/stretchr/testify/assert"
    38  	"github.com/stretchr/testify/require"
    39  )
    40  
    41  var (
    42  	privkey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
    43  	pubkey     = &privkey.PublicKey
    44  )
    45  
    46  var rnd = rand.New(rand.NewSource(time.Now().UnixNano()))
    47  
    48  func randomString(strlen int) string {
    49  	b := make([]byte, strlen)
    50  	rnd.Read(b)
    51  	return string(b)
    52  }
    53  
    54  //testgetsetid测试ID键的编码/解码和设置/获取。
    55  func TestGetSetID(t *testing.T) {
    56  	id := ID("someid")
    57  	var r Record
    58  	r.Set(id)
    59  
    60  	var id2 ID
    61  	require.NoError(t, r.Load(&id2))
    62  	assert.Equal(t, id, id2)
    63  }
    64  
    65  //testgetsetip4测试IP密钥的编码/解码和设置/获取。
    66  func TestGetSetIP4(t *testing.T) {
    67  	ip := IP{192, 168, 0, 3}
    68  	var r Record
    69  	r.Set(ip)
    70  
    71  	var ip2 IP
    72  	require.NoError(t, r.Load(&ip2))
    73  	assert.Equal(t, ip, ip2)
    74  }
    75  
    76  //testgetsetip6测试IP密钥的编码/解码和设置/获取。
    77  func TestGetSetIP6(t *testing.T) {
    78  	ip := IP{0x20, 0x01, 0x48, 0x60, 0, 0, 0x20, 0x01, 0, 0, 0, 0, 0, 0, 0x00, 0x68}
    79  	var r Record
    80  	r.Set(ip)
    81  
    82  	var ip2 IP
    83  	require.NoError(t, r.Load(&ip2))
    84  	assert.Equal(t, ip, ip2)
    85  }
    86  
    87  //testgetsetdiscport测试discport密钥的编码/解码和设置/获取。
    88  func TestGetSetUDP(t *testing.T) {
    89  	port := UDP(30309)
    90  	var r Record
    91  	r.Set(port)
    92  
    93  	var port2 UDP
    94  	require.NoError(t, r.Load(&port2))
    95  	assert.Equal(t, port, port2)
    96  }
    97  
    98  //testgetsetsecp256k1测试secp256k1密钥的编码/解码和设置/获取。
    99  func TestGetSetSecp256k1(t *testing.T) {
   100  	var r Record
   101  	if err := SignV4(&r, privkey); err != nil {
   102  		t.Fatal(err)
   103  	}
   104  
   105  	var pk Secp256k1
   106  	require.NoError(t, r.Load(&pk))
   107  	assert.EqualValues(t, pubkey, &pk)
   108  }
   109  
   110  func TestLoadErrors(t *testing.T) {
   111  	var r Record
   112  	ip4 := IP{127, 0, 0, 1}
   113  	r.Set(ip4)
   114  
   115  //检查是否有钥匙丢失的错误。
   116  	var udp UDP
   117  	err := r.Load(&udp)
   118  	if !IsNotFound(err) {
   119  		t.Error("IsNotFound should return true for missing key")
   120  	}
   121  	assert.Equal(t, &KeyError{Key: udp.ENRKey(), Err: errNotFound}, err)
   122  
   123  //检查无效密钥的错误。
   124  	var list []uint
   125  	err = r.Load(WithEntry(ip4.ENRKey(), &list))
   126  	kerr, ok := err.(*KeyError)
   127  	if !ok {
   128  		t.Fatalf("expected KeyError, got %T", err)
   129  	}
   130  	assert.Equal(t, kerr.Key, ip4.ENRKey())
   131  	assert.Error(t, kerr.Err)
   132  	if IsNotFound(err) {
   133  		t.Error("IsNotFound should return false for decoding errors")
   134  	}
   135  }
   136  
   137  //testsortedgetandset生成排序对切片的测试。
   138  func TestSortedGetAndSet(t *testing.T) {
   139  	type pair struct {
   140  		k string
   141  		v uint32
   142  	}
   143  
   144  	for _, tt := range []struct {
   145  		input []pair
   146  		want  []pair
   147  	}{
   148  		{
   149  			input: []pair{{"a", 1}, {"c", 2}, {"b", 3}},
   150  			want:  []pair{{"a", 1}, {"b", 3}, {"c", 2}},
   151  		},
   152  		{
   153  			input: []pair{{"a", 1}, {"c", 2}, {"b", 3}, {"d", 4}, {"a", 5}, {"bb", 6}},
   154  			want:  []pair{{"a", 5}, {"b", 3}, {"bb", 6}, {"c", 2}, {"d", 4}},
   155  		},
   156  		{
   157  			input: []pair{{"c", 2}, {"b", 3}, {"d", 4}, {"a", 5}, {"bb", 6}},
   158  			want:  []pair{{"a", 5}, {"b", 3}, {"bb", 6}, {"c", 2}, {"d", 4}},
   159  		},
   160  	} {
   161  		var r Record
   162  		for _, i := range tt.input {
   163  			r.Set(WithEntry(i.k, &i.v))
   164  		}
   165  		for i, w := range tt.want {
   166  //设置r.pair[i]中的got's键,以便保留对的顺序
   167  			got := pair{k: r.pairs[i].k}
   168  			assert.NoError(t, r.Load(WithEntry(w.k, &got.v)))
   169  			assert.Equal(t, w, got)
   170  		}
   171  	}
   172  }
   173  
   174  //testDirty测试在记录中设置新的键/值对时记录签名删除。
   175  func TestDirty(t *testing.T) {
   176  	var r Record
   177  
   178  	if r.Signed() {
   179  		t.Error("Signed returned true for zero record")
   180  	}
   181  	if _, err := rlp.EncodeToBytes(r); err != errEncodeUnsigned {
   182  		t.Errorf("expected errEncodeUnsigned, got %#v", err)
   183  	}
   184  
   185  	require.NoError(t, SignV4(&r, privkey))
   186  	if !r.Signed() {
   187  		t.Error("Signed return false for signed record")
   188  	}
   189  	_, err := rlp.EncodeToBytes(r)
   190  	assert.NoError(t, err)
   191  
   192  	r.SetSeq(3)
   193  	if r.Signed() {
   194  		t.Error("Signed returned true for modified record")
   195  	}
   196  	if _, err := rlp.EncodeToBytes(r); err != errEncodeUnsigned {
   197  		t.Errorf("expected errEncodeUnsigned, got %#v", err)
   198  	}
   199  }
   200  
   201  //使用记录中的现有键设置新值时,testgetsetoverwrite测试值overwrite。
   202  func TestGetSetOverwrite(t *testing.T) {
   203  	var r Record
   204  
   205  	ip := IP{192, 168, 0, 3}
   206  	r.Set(ip)
   207  
   208  	ip2 := IP{192, 168, 0, 4}
   209  	r.Set(ip2)
   210  
   211  	var ip3 IP
   212  	require.NoError(t, r.Load(&ip3))
   213  	assert.Equal(t, ip2, ip3)
   214  }
   215  
   216  //testsignencodeanddecode测试记录的签名、rlp编码和rlp解码。
   217  func TestSignEncodeAndDecode(t *testing.T) {
   218  	var r Record
   219  	r.Set(UDP(30303))
   220  	r.Set(IP{127, 0, 0, 1})
   221  	require.NoError(t, SignV4(&r, privkey))
   222  
   223  	blob, err := rlp.EncodeToBytes(r)
   224  	require.NoError(t, err)
   225  
   226  	var r2 Record
   227  	require.NoError(t, rlp.DecodeBytes(blob, &r2))
   228  	assert.Equal(t, r, r2)
   229  
   230  	blob2, err := rlp.EncodeToBytes(r2)
   231  	require.NoError(t, err)
   232  	assert.Equal(t, blob, blob2)
   233  }
   234  
   235  func TestNodeAddr(t *testing.T) {
   236  	var r Record
   237  	if addr := r.NodeAddr(); addr != nil {
   238  		t.Errorf("wrong address on empty record: got %v, want %v", addr, nil)
   239  	}
   240  
   241  	require.NoError(t, SignV4(&r, privkey))
   242  	expected := "a448f24c6d18e575453db13171562b71999873db5b286df957af199ec94617f7"
   243  	assert.Equal(t, expected, hex.EncodeToString(r.NodeAddr()))
   244  }
   245  
   246  var pyRecord, _ = hex.DecodeString("f884b8407098ad865b00a582051940cb9cf36836572411a47278783077011599ed5cd16b76f2635f4e234738f30813a89eb9137e3e3df5266e3a1f11df72ecf1145ccb9c01826964827634826970847f00000189736563703235366b31a103ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1400f3258cd31388375647082765f")
   247  
   248  //testpythorintrop检查是否可以解码和验证由python生成的记录
   249  //实施。
   250  func TestPythonInterop(t *testing.T) {
   251  	var r Record
   252  	if err := rlp.DecodeBytes(pyRecord, &r); err != nil {
   253  		t.Fatalf("can't decode: %v", err)
   254  	}
   255  
   256  	var (
   257  		wantAddr, _ = hex.DecodeString("a448f24c6d18e575453db13171562b71999873db5b286df957af199ec94617f7")
   258  		wantSeq     = uint64(1)
   259  		wantIP      = IP{127, 0, 0, 1}
   260  		wantUDP     = UDP(30303)
   261  	)
   262  	if r.Seq() != wantSeq {
   263  		t.Errorf("wrong seq: got %d, want %d", r.Seq(), wantSeq)
   264  	}
   265  	if addr := r.NodeAddr(); !bytes.Equal(addr, wantAddr) {
   266  		t.Errorf("wrong addr: got %x, want %x", addr, wantAddr)
   267  	}
   268  	want := map[Entry]interface{}{new(IP): &wantIP, new(UDP): &wantUDP}
   269  	for k, v := range want {
   270  		desc := fmt.Sprintf("loading key %q", k.ENRKey())
   271  		if assert.NoError(t, r.Load(k), desc) {
   272  			assert.Equal(t, k, v, desc)
   273  		}
   274  	}
   275  }
   276  
   277  //无法对记录大于sizelimit字节的TestRecordToObig测试进行签名。
   278  func TestRecordTooBig(t *testing.T) {
   279  	var r Record
   280  	key := randomString(10)
   281  
   282  //为随机键设置大值,预计错误
   283  	r.Set(WithEntry(key, randomString(SizeLimit)))
   284  	if err := SignV4(&r, privkey); err != errTooBig {
   285  		t.Fatalf("expected to get errTooBig, got %#v", err)
   286  	}
   287  
   288  //为随机键设置一个可接受的值,不期望出现错误
   289  	r.Set(WithEntry(key, randomString(100)))
   290  	require.NoError(t, SignV4(&r, privkey))
   291  }
   292  
   293  //testsignencodeanddecoderandom测试包含随机键/值对的记录的编码/解码。
   294  func TestSignEncodeAndDecodeRandom(t *testing.T) {
   295  	var r Record
   296  
   297  //用于测试的随机键/值对
   298  	pairs := map[string]uint32{}
   299  	for i := 0; i < 10; i++ {
   300  		key := randomString(7)
   301  		value := rnd.Uint32()
   302  		pairs[key] = value
   303  		r.Set(WithEntry(key, &value))
   304  	}
   305  
   306  	require.NoError(t, SignV4(&r, privkey))
   307  	_, err := rlp.EncodeToBytes(r)
   308  	require.NoError(t, err)
   309  
   310  	for k, v := range pairs {
   311  		desc := fmt.Sprintf("key %q", k)
   312  		var got uint32
   313  		buf := WithEntry(k, &got)
   314  		require.NoError(t, r.Load(buf), desc)
   315  		require.Equal(t, v, got, desc)
   316  	}
   317  }
   318  
   319  func BenchmarkDecode(b *testing.B) {
   320  	var r Record
   321  	for i := 0; i < b.N; i++ {
   322  		rlp.DecodeBytes(pyRecord, &r)
   323  	}
   324  	b.StopTimer()
   325  	r.NodeAddr()
   326  }