github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/p2p/enr/enr_test.go (about)

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