github.com/cheng762/platon-go@v1.8.17-0.20190529111256-7deff2d7be26/p2p/enr/enr_test.go (about) 1 // Copyright 2017 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package enr 18 19 import ( 20 "encoding/hex" 21 "fmt" 22 "math/rand" 23 "testing" 24 "time" 25 26 "github.com/PlatONnetwork/PlatON-Go/crypto" 27 "github.com/PlatONnetwork/PlatON-Go/rlp" 28 "github.com/stretchr/testify/assert" 29 "github.com/stretchr/testify/require" 30 ) 31 32 var ( 33 privkey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") 34 pubkey = &privkey.PublicKey 35 ) 36 37 var rnd = rand.New(rand.NewSource(time.Now().UnixNano())) 38 39 func randomString(strlen int) string { 40 b := make([]byte, strlen) 41 rnd.Read(b) 42 return string(b) 43 } 44 45 // TestGetSetID tests encoding/decoding and setting/getting of the ID key. 46 func TestGetSetID(t *testing.T) { 47 id := ID("someid") 48 var r Record 49 r.Set(id) 50 51 var id2 ID 52 require.NoError(t, r.Load(&id2)) 53 assert.Equal(t, id, id2) 54 } 55 56 // TestGetSetIP4 tests encoding/decoding and setting/getting of the IP key. 57 func TestGetSetIP4(t *testing.T) { 58 ip := IP{192, 168, 0, 3} 59 var r Record 60 r.Set(ip) 61 62 var ip2 IP 63 require.NoError(t, r.Load(&ip2)) 64 assert.Equal(t, ip, ip2) 65 } 66 67 // TestGetSetIP6 tests encoding/decoding and setting/getting of the IP key. 68 func TestGetSetIP6(t *testing.T) { 69 ip := IP{0x20, 0x01, 0x48, 0x60, 0, 0, 0x20, 0x01, 0, 0, 0, 0, 0, 0, 0x00, 0x68} 70 var r Record 71 r.Set(ip) 72 73 var ip2 IP 74 require.NoError(t, r.Load(&ip2)) 75 assert.Equal(t, ip, ip2) 76 } 77 78 // TestGetSetDiscPort tests encoding/decoding and setting/getting of the DiscPort key. 79 func TestGetSetUDP(t *testing.T) { 80 port := UDP(30309) 81 var r Record 82 r.Set(port) 83 84 var port2 UDP 85 require.NoError(t, r.Load(&port2)) 86 assert.Equal(t, port, port2) 87 } 88 89 // TestGetSetSecp256k1 tests encoding/decoding and setting/getting of the Secp256k1 key. 90 func TestGetSetSecp256k1(t *testing.T) { 91 var r Record 92 if err := SignV4(&r, privkey); err != nil { 93 t.Fatal(err) 94 } 95 96 var pk Secp256k1 97 require.NoError(t, r.Load(&pk)) 98 assert.EqualValues(t, pubkey, &pk) 99 } 100 101 func TestLoadErrors(t *testing.T) { 102 var r Record 103 ip4 := IP{127, 0, 0, 1} 104 r.Set(ip4) 105 106 // Check error for missing keys. 107 var udp UDP 108 err := r.Load(&udp) 109 if !IsNotFound(err) { 110 t.Error("IsNotFound should return true for missing key") 111 } 112 assert.Equal(t, &KeyError{Key: udp.ENRKey(), Err: errNotFound}, err) 113 114 // Check error for invalid keys. 115 var list []uint 116 err = r.Load(WithEntry(ip4.ENRKey(), &list)) 117 kerr, ok := err.(*KeyError) 118 if !ok { 119 t.Fatalf("expected KeyError, got %T", err) 120 } 121 assert.Equal(t, kerr.Key, ip4.ENRKey()) 122 assert.Error(t, kerr.Err) 123 if IsNotFound(err) { 124 t.Error("IsNotFound should return false for decoding errors") 125 } 126 } 127 128 // TestSortedGetAndSet tests that Set produced a sorted pairs slice. 129 func TestSortedGetAndSet(t *testing.T) { 130 type pair struct { 131 k string 132 v uint32 133 } 134 135 for _, tt := range []struct { 136 input []pair 137 want []pair 138 }{ 139 { 140 input: []pair{{"a", 1}, {"c", 2}, {"b", 3}}, 141 want: []pair{{"a", 1}, {"b", 3}, {"c", 2}}, 142 }, 143 { 144 input: []pair{{"a", 1}, {"c", 2}, {"b", 3}, {"d", 4}, {"a", 5}, {"bb", 6}}, 145 want: []pair{{"a", 5}, {"b", 3}, {"bb", 6}, {"c", 2}, {"d", 4}}, 146 }, 147 { 148 input: []pair{{"c", 2}, {"b", 3}, {"d", 4}, {"a", 5}, {"bb", 6}}, 149 want: []pair{{"a", 5}, {"b", 3}, {"bb", 6}, {"c", 2}, {"d", 4}}, 150 }, 151 } { 152 var r Record 153 for _, i := range tt.input { 154 r.Set(WithEntry(i.k, &i.v)) 155 } 156 for i, w := range tt.want { 157 // set got's key from r.pair[i], so that we preserve order of pairs 158 got := pair{k: r.pairs[i].k} 159 assert.NoError(t, r.Load(WithEntry(w.k, &got.v))) 160 assert.Equal(t, w, got) 161 } 162 } 163 } 164 165 // TestDirty tests record signature removal on setting of new key/value pair in record. 166 func TestDirty(t *testing.T) { 167 var r Record 168 169 if r.Signed() { 170 t.Error("Signed returned true for zero record") 171 } 172 if _, err := rlp.EncodeToBytes(r); err != errEncodeUnsigned { 173 t.Errorf("expected errEncodeUnsigned, got %#v", err) 174 } 175 176 require.NoError(t, SignV4(&r, privkey)) 177 if !r.Signed() { 178 t.Error("Signed return false for signed record") 179 } 180 _, err := rlp.EncodeToBytes(r) 181 assert.NoError(t, err) 182 183 r.SetSeq(3) 184 if r.Signed() { 185 t.Error("Signed returned true for modified record") 186 } 187 if _, err := rlp.EncodeToBytes(r); err != errEncodeUnsigned { 188 t.Errorf("expected errEncodeUnsigned, got %#v", err) 189 } 190 } 191 192 // TestGetSetOverwrite tests value overwrite when setting a new value with an existing key in record. 193 func TestGetSetOverwrite(t *testing.T) { 194 var r Record 195 196 ip := IP{192, 168, 0, 3} 197 r.Set(ip) 198 199 ip2 := IP{192, 168, 0, 4} 200 r.Set(ip2) 201 202 var ip3 IP 203 require.NoError(t, r.Load(&ip3)) 204 assert.Equal(t, ip2, ip3) 205 } 206 207 // TestSignEncodeAndDecode tests signing, RLP encoding and RLP decoding of a record. 208 func TestSignEncodeAndDecode(t *testing.T) { 209 var r Record 210 r.Set(UDP(16789)) 211 r.Set(IP{127, 0, 0, 1}) 212 require.NoError(t, SignV4(&r, privkey)) 213 214 blob, err := rlp.EncodeToBytes(r) 215 require.NoError(t, err) 216 217 var r2 Record 218 require.NoError(t, rlp.DecodeBytes(blob, &r2)) 219 assert.Equal(t, r, r2) 220 221 blob2, err := rlp.EncodeToBytes(r2) 222 require.NoError(t, err) 223 assert.Equal(t, blob, blob2) 224 } 225 226 func TestNodeAddr(t *testing.T) { 227 var r Record 228 if addr := r.NodeAddr(); addr != nil { 229 t.Errorf("wrong address on empty record: got %v, want %v", addr, nil) 230 } 231 232 require.NoError(t, SignV4(&r, privkey)) 233 expected := "a448f24c6d18e575453db13171562b71999873db5b286df957af199ec94617f7" 234 assert.Equal(t, expected, hex.EncodeToString(r.NodeAddr())) 235 } 236 237 var pyRecord, _ = hex.DecodeString("f884b8407098ad865b00a582051940cb9cf36836572411a47278783077011599ed5cd16b76f2635f4e234738f30813a89eb9137e3e3df5266e3a1f11df72ecf1145ccb9c01826964827634826970847f00000189736563703235366b31a103ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1400f3258cd31388375647082765f") 238 239 // TestPythonInterop checks that we can decode and verify a record produced by the Python 240 // implementation. 241 /*func TestPythonInterop(t *testing.T) { 242 var r Record 243 if err := rlp.DecodeBytes(pyRecord, &r); err != nil { 244 t.Fatalf("can't decode: %v", err) 245 } 246 247 var ( 248 wantAddr, _ = hex.DecodeString("a448f24c6d18e575453db13171562b71999873db5b286df957af199ec94617f7") 249 wantSeq = uint64(1) 250 wantIP = IP{127, 0, 0, 1} 251 wantUDP = UDP(16789) 252 ) 253 if r.Seq() != wantSeq { 254 t.Errorf("wrong seq: got %d, want %d", r.Seq(), wantSeq) 255 } 256 if addr := r.NodeAddr(); !bytes.Equal(addr, wantAddr) { 257 t.Errorf("wrong addr: got %x, want %x", addr, wantAddr) 258 } 259 want := map[Entry]interface{}{new(IP): &wantIP, new(UDP): &wantUDP} 260 for k, v := range want { 261 desc := fmt.Sprintf("loading key %q", k.ENRKey()) 262 if assert.NoError(t, r.Load(k), desc) { 263 assert.Equal(t, k, v, desc) 264 } 265 } 266 }*/ 267 268 // TestRecordTooBig tests that records bigger than SizeLimit bytes cannot be signed. 269 func TestRecordTooBig(t *testing.T) { 270 var r Record 271 key := randomString(10) 272 273 // set a big value for random key, expect error 274 r.Set(WithEntry(key, randomString(SizeLimit))) 275 if err := SignV4(&r, privkey); err != errTooBig { 276 t.Fatalf("expected to get errTooBig, got %#v", err) 277 } 278 279 // set an acceptable value for random key, expect no error 280 r.Set(WithEntry(key, randomString(100))) 281 require.NoError(t, SignV4(&r, privkey)) 282 } 283 284 // TestSignEncodeAndDecodeRandom tests encoding/decoding of records containing random key/value pairs. 285 func TestSignEncodeAndDecodeRandom(t *testing.T) { 286 var r Record 287 288 // random key/value pairs for testing 289 pairs := map[string]uint32{} 290 for i := 0; i < 10; i++ { 291 key := randomString(7) 292 value := rnd.Uint32() 293 pairs[key] = value 294 r.Set(WithEntry(key, &value)) 295 } 296 297 require.NoError(t, SignV4(&r, privkey)) 298 _, err := rlp.EncodeToBytes(r) 299 require.NoError(t, err) 300 301 for k, v := range pairs { 302 desc := fmt.Sprintf("key %q", k) 303 var got uint32 304 buf := WithEntry(k, &got) 305 require.NoError(t, r.Load(buf), desc) 306 require.Equal(t, v, got, desc) 307 } 308 } 309 310 func BenchmarkDecode(b *testing.B) { 311 var r Record 312 for i := 0; i < b.N; i++ { 313 rlp.DecodeBytes(pyRecord, &r) 314 } 315 b.StopTimer() 316 r.NodeAddr() 317 }