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