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