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 }