github.com/ethereum/go-ethereum@v1.16.1/p2p/enode/node_test.go (about) 1 // Copyright 2018 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 enode 18 19 import ( 20 "bytes" 21 "encoding/hex" 22 "fmt" 23 "math/big" 24 "net/netip" 25 "testing" 26 "testing/quick" 27 28 "github.com/ethereum/go-ethereum/p2p/enr" 29 "github.com/ethereum/go-ethereum/rlp" 30 "github.com/stretchr/testify/assert" 31 ) 32 33 var pyRecord, _ = hex.DecodeString("f884b8407098ad865b00a582051940cb9cf36836572411a47278783077011599ed5cd16b76f2635f4e234738f30813a89eb9137e3e3df5266e3a1f11df72ecf1145ccb9c01826964827634826970847f00000189736563703235366b31a103ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1400f3258cd31388375647082765f") 34 35 // TestPythonInterop checks that we can decode and verify a record produced by the Python 36 // implementation. 37 func TestPythonInterop(t *testing.T) { 38 var r enr.Record 39 if err := rlp.DecodeBytes(pyRecord, &r); err != nil { 40 t.Fatalf("can't decode: %v", err) 41 } 42 n, err := New(ValidSchemes, &r) 43 if err != nil { 44 t.Fatalf("can't verify record: %v", err) 45 } 46 47 var ( 48 wantID = HexID("a448f24c6d18e575453db13171562b71999873db5b286df957af199ec94617f7") 49 wantSeq = uint64(1) 50 wantIP = enr.IPv4{127, 0, 0, 1} 51 wantUDP = enr.UDP(30303) 52 ) 53 if n.Seq() != wantSeq { 54 t.Errorf("wrong seq: got %d, want %d", n.Seq(), wantSeq) 55 } 56 if n.ID() != wantID { 57 t.Errorf("wrong id: got %x, want %x", n.ID(), wantID) 58 } 59 want := map[enr.Entry]interface{}{new(enr.IPv4): &wantIP, new(enr.UDP): &wantUDP} 60 for k, v := range want { 61 desc := fmt.Sprintf("loading key %q", k.ENRKey()) 62 if assert.NoError(t, n.Load(k), desc) { 63 assert.Equal(t, k, v, desc) 64 } 65 } 66 } 67 68 func TestNodeEndpoints(t *testing.T) { 69 id := HexID("00000000000000806ad9b61fa5ae014307ebdc964253adcd9f2c0a392aa11abc") 70 type endpointTest struct { 71 name string 72 node *Node 73 wantIP netip.Addr 74 wantUDP int 75 wantTCP int 76 wantQUIC int 77 wantDNS string 78 } 79 tests := []endpointTest{ 80 { 81 name: "no-addr", 82 node: func() *Node { 83 var r enr.Record 84 return SignNull(&r, id) 85 }(), 86 }, 87 { 88 name: "udp-only", 89 node: func() *Node { 90 var r enr.Record 91 r.Set(enr.UDP(9000)) 92 return SignNull(&r, id) 93 }(), 94 wantUDP: 9000, 95 }, 96 { 97 name: "tcp-only", 98 node: func() *Node { 99 var r enr.Record 100 r.Set(enr.TCP(9000)) 101 return SignNull(&r, id) 102 }(), 103 wantTCP: 9000, 104 }, 105 { 106 name: "quic-only", 107 node: func() *Node { 108 var r enr.Record 109 r.Set(enr.QUIC(9000)) 110 return SignNull(&r, id) 111 }(), 112 }, 113 { 114 name: "quic6-only", 115 node: func() *Node { 116 var r enr.Record 117 r.Set(enr.QUIC6(9000)) 118 return SignNull(&r, id) 119 }(), 120 }, 121 { 122 name: "ipv4-only-loopback", 123 node: func() *Node { 124 var r enr.Record 125 r.Set(enr.IPv4Addr(netip.MustParseAddr("127.0.0.1"))) 126 return SignNull(&r, id) 127 }(), 128 wantIP: netip.MustParseAddr("127.0.0.1"), 129 }, 130 { 131 name: "ipv4-only-unspecified", 132 node: func() *Node { 133 var r enr.Record 134 r.Set(enr.IPv4Addr(netip.MustParseAddr("0.0.0.0"))) 135 return SignNull(&r, id) 136 }(), 137 wantIP: netip.MustParseAddr("0.0.0.0"), 138 }, 139 { 140 name: "ipv4-only", 141 node: func() *Node { 142 var r enr.Record 143 r.Set(enr.IPv4Addr(netip.MustParseAddr("99.22.33.1"))) 144 return SignNull(&r, id) 145 }(), 146 wantIP: netip.MustParseAddr("99.22.33.1"), 147 }, 148 { 149 name: "ipv6-only", 150 node: func() *Node { 151 var r enr.Record 152 r.Set(enr.IPv6Addr(netip.MustParseAddr("2001::ff00:0042:8329"))) 153 return SignNull(&r, id) 154 }(), 155 wantIP: netip.MustParseAddr("2001::ff00:0042:8329"), 156 }, 157 { 158 name: "ipv4-loopback-and-ipv6-global", 159 node: func() *Node { 160 var r enr.Record 161 r.Set(enr.IPv4Addr(netip.MustParseAddr("127.0.0.1"))) 162 r.Set(enr.UDP(30304)) 163 r.Set(enr.IPv6Addr(netip.MustParseAddr("2001::ff00:0042:8329"))) 164 r.Set(enr.UDP6(30306)) 165 return SignNull(&r, id) 166 }(), 167 wantIP: netip.MustParseAddr("2001::ff00:0042:8329"), 168 wantUDP: 30306, 169 }, 170 { 171 name: "ipv4-unspecified-and-ipv6-loopback", 172 node: func() *Node { 173 var r enr.Record 174 r.Set(enr.IPv4Addr(netip.MustParseAddr("0.0.0.0"))) 175 r.Set(enr.IPv6Addr(netip.MustParseAddr("::1"))) 176 return SignNull(&r, id) 177 }(), 178 wantIP: netip.MustParseAddr("::1"), 179 }, 180 { 181 name: "ipv4-private-and-ipv6-global", 182 node: func() *Node { 183 var r enr.Record 184 r.Set(enr.IPv4Addr(netip.MustParseAddr("192.168.2.2"))) 185 r.Set(enr.UDP(30304)) 186 r.Set(enr.IPv6Addr(netip.MustParseAddr("2001::ff00:0042:8329"))) 187 r.Set(enr.UDP6(30306)) 188 return SignNull(&r, id) 189 }(), 190 wantIP: netip.MustParseAddr("2001::ff00:0042:8329"), 191 wantUDP: 30306, 192 }, 193 { 194 name: "ipv4-local-and-ipv6-global", 195 node: func() *Node { 196 var r enr.Record 197 r.Set(enr.IPv4Addr(netip.MustParseAddr("169.254.2.6"))) 198 r.Set(enr.UDP(30304)) 199 r.Set(enr.IPv6Addr(netip.MustParseAddr("2001::ff00:0042:8329"))) 200 r.Set(enr.UDP6(30306)) 201 return SignNull(&r, id) 202 }(), 203 wantIP: netip.MustParseAddr("2001::ff00:0042:8329"), 204 wantUDP: 30306, 205 }, 206 { 207 name: "ipv4-private-and-ipv6-private", 208 node: func() *Node { 209 var r enr.Record 210 r.Set(enr.IPv4Addr(netip.MustParseAddr("192.168.2.2"))) 211 r.Set(enr.UDP(30304)) 212 r.Set(enr.IPv6Addr(netip.MustParseAddr("fd00::abcd:1"))) 213 r.Set(enr.UDP6(30306)) 214 return SignNull(&r, id) 215 }(), 216 wantIP: netip.MustParseAddr("192.168.2.2"), 217 wantUDP: 30304, 218 }, 219 { 220 name: "ipv4-private-and-ipv6-link-local", 221 node: func() *Node { 222 var r enr.Record 223 r.Set(enr.IPv4Addr(netip.MustParseAddr("192.168.2.2"))) 224 r.Set(enr.UDP(30304)) 225 r.Set(enr.IPv6Addr(netip.MustParseAddr("fe80::1"))) 226 r.Set(enr.UDP6(30306)) 227 return SignNull(&r, id) 228 }(), 229 wantIP: netip.MustParseAddr("192.168.2.2"), 230 wantUDP: 30304, 231 }, 232 { 233 name: "ipv4-quic", 234 node: func() *Node { 235 var r enr.Record 236 r.Set(enr.IPv4Addr(netip.MustParseAddr("99.22.33.1"))) 237 r.Set(enr.QUIC(9001)) 238 return SignNull(&r, id) 239 }(), 240 wantIP: netip.MustParseAddr("99.22.33.1"), 241 wantQUIC: 9001, 242 }, 243 { // Because the node is IPv4, the quic6 entry won't be loaded. 244 name: "ipv4-quic6", 245 node: func() *Node { 246 var r enr.Record 247 r.Set(enr.IPv4Addr(netip.MustParseAddr("99.22.33.1"))) 248 r.Set(enr.QUIC6(9001)) 249 return SignNull(&r, id) 250 }(), 251 wantIP: netip.MustParseAddr("99.22.33.1"), 252 }, 253 { 254 name: "ipv6-quic", 255 node: func() *Node { 256 var r enr.Record 257 r.Set(enr.IPv6Addr(netip.MustParseAddr("2001::ff00:0042:8329"))) 258 r.Set(enr.QUIC(9001)) 259 return SignNull(&r, id) 260 }(), 261 wantIP: netip.MustParseAddr("2001::ff00:0042:8329"), 262 }, 263 { 264 name: "ipv6-quic6", 265 node: func() *Node { 266 var r enr.Record 267 r.Set(enr.IPv6Addr(netip.MustParseAddr("2001::ff00:0042:8329"))) 268 r.Set(enr.QUIC6(9001)) 269 return SignNull(&r, id) 270 }(), 271 wantIP: netip.MustParseAddr("2001::ff00:0042:8329"), 272 wantQUIC: 9001, 273 }, 274 { 275 name: "dns-only", 276 node: func() *Node { 277 var r enr.Record 278 r.Set(enr.UDP(30303)) 279 r.Set(enr.TCP(30303)) 280 n := SignNull(&r, id).WithHostname("example.com") 281 return n 282 }(), 283 wantTCP: 30303, 284 wantUDP: 30303, 285 wantDNS: "example.com", 286 }, 287 } 288 289 for _, test := range tests { 290 t.Run(test.name, func(t *testing.T) { 291 if test.wantIP != test.node.IPAddr() { 292 t.Errorf("node has wrong IP %v, want %v", test.node.IPAddr(), test.wantIP) 293 } 294 if test.wantUDP != test.node.UDP() { 295 t.Errorf("node has wrong UDP port %d, want %d", test.node.UDP(), test.wantUDP) 296 } 297 if test.wantTCP != test.node.TCP() { 298 t.Errorf("node has wrong TCP port %d, want %d", test.node.TCP(), test.wantTCP) 299 } 300 if quic, _ := test.node.QUICEndpoint(); test.wantQUIC != int(quic.Port()) { 301 t.Errorf("node has wrong QUIC port %d, want %d", quic.Port(), test.wantQUIC) 302 } 303 if test.wantDNS != test.node.Hostname() { 304 t.Errorf("node has wrong DNS name %s, want %s", test.node.Hostname(), test.wantDNS) 305 } 306 }) 307 } 308 } 309 310 func TestHexID(t *testing.T) { 311 ref := ID{0, 0, 0, 0, 0, 0, 0, 128, 106, 217, 182, 31, 165, 174, 1, 67, 7, 235, 220, 150, 66, 83, 173, 205, 159, 44, 10, 57, 42, 161, 26, 188} 312 id1 := HexID("0x00000000000000806ad9b61fa5ae014307ebdc964253adcd9f2c0a392aa11abc") 313 id2 := HexID("00000000000000806ad9b61fa5ae014307ebdc964253adcd9f2c0a392aa11abc") 314 315 if id1 != ref { 316 t.Errorf("wrong id1\ngot %v\nwant %v", id1[:], ref[:]) 317 } 318 if id2 != ref { 319 t.Errorf("wrong id2\ngot %v\nwant %v", id2[:], ref[:]) 320 } 321 } 322 323 func TestID_textEncoding(t *testing.T) { 324 ref := ID{ 325 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 326 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 327 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30, 328 0x31, 0x32, 329 } 330 hex := "0102030405060708091011121314151617181920212223242526272829303132" 331 332 text, err := ref.MarshalText() 333 if err != nil { 334 t.Fatal(err) 335 } 336 if !bytes.Equal(text, []byte(hex)) { 337 t.Fatalf("text encoding did not match\nexpected: %s\ngot: %s", hex, text) 338 } 339 340 id := new(ID) 341 if err := id.UnmarshalText(text); err != nil { 342 t.Fatal(err) 343 } 344 if *id != ref { 345 t.Fatalf("text decoding did not match\nexpected: %s\ngot: %s", ref, id) 346 } 347 } 348 349 func TestID_distcmp(t *testing.T) { 350 distcmpBig := func(target, a, b ID) int { 351 tbig := new(big.Int).SetBytes(target[:]) 352 abig := new(big.Int).SetBytes(a[:]) 353 bbig := new(big.Int).SetBytes(b[:]) 354 return new(big.Int).Xor(tbig, abig).Cmp(new(big.Int).Xor(tbig, bbig)) 355 } 356 if err := quick.CheckEqual(DistCmp, distcmpBig, nil); err != nil { 357 t.Error(err) 358 } 359 } 360 361 // The random tests is likely to miss the case where a and b are equal, 362 // this test checks it explicitly. 363 func TestID_distcmpEqual(t *testing.T) { 364 base := ID{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} 365 x := ID{15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0} 366 if DistCmp(base, x, x) != 0 { 367 t.Errorf("DistCmp(base, x, x) != 0") 368 } 369 } 370 371 func TestID_logdist(t *testing.T) { 372 logdistBig := func(a, b ID) int { 373 abig, bbig := new(big.Int).SetBytes(a[:]), new(big.Int).SetBytes(b[:]) 374 return new(big.Int).Xor(abig, bbig).BitLen() 375 } 376 if err := quick.CheckEqual(LogDist, logdistBig, nil); err != nil { 377 t.Error(err) 378 } 379 } 380 381 // The random tests is likely to miss the case where a and b are equal, 382 // this test checks it explicitly. 383 func TestID_logdistEqual(t *testing.T) { 384 x := ID{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} 385 if LogDist(x, x) != 0 { 386 t.Errorf("LogDist(x, x) != 0") 387 } 388 }