github.com/kisexp/xdchain@v0.0.0-20211206025815-490d6b732aa7/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" 25 "strings" 26 "testing" 27 "testing/quick" 28 29 "github.com/kisexp/xdchain/p2p/enr" 30 "github.com/kisexp/xdchain/rlp" 31 "github.com/stretchr/testify/assert" 32 ) 33 34 var pyRecord, _ = hex.DecodeString("f884b8407098ad865b00a582051940cb9cf36836572411a47278783077011599ed5cd16b76f2635f4e234738f30813a89eb9137e3e3df5266e3a1f11df72ecf1145ccb9c01826964827634826970847f00000189736563703235366b31a103ca634cae0d49acb401d8a4c6b6fe8c55b70d115bf400769cc1400f3258cd31388375647082765f") 35 36 // TestPythonInterop checks that we can decode and verify a record produced by the Python 37 // implementation. 38 func TestPythonInterop(t *testing.T) { 39 var r enr.Record 40 if err := rlp.DecodeBytes(pyRecord, &r); err != nil { 41 t.Fatalf("can't decode: %v", err) 42 } 43 n, err := New(ValidSchemes, &r) 44 if err != nil { 45 t.Fatalf("can't verify record: %v", err) 46 } 47 48 var ( 49 wantID = HexID("a448f24c6d18e575453db13171562b71999873db5b286df957af199ec94617f7") 50 wantSeq = uint64(1) 51 wantIP = enr.IPv4{127, 0, 0, 1} 52 wantUDP = enr.UDP(30303) 53 ) 54 if n.Seq() != wantSeq { 55 t.Errorf("wrong seq: got %d, want %d", n.Seq(), wantSeq) 56 } 57 if n.ID() != wantID { 58 t.Errorf("wrong id: got %x, want %x", n.ID(), wantID) 59 } 60 want := map[enr.Entry]interface{}{new(enr.IPv4): &wantIP, new(enr.UDP): &wantUDP} 61 for k, v := range want { 62 desc := fmt.Sprintf("loading key %q", k.ENRKey()) 63 if assert.NoError(t, n.Load(k), desc) { 64 assert.Equal(t, k, v, desc) 65 } 66 } 67 } 68 69 func TestHexID(t *testing.T) { 70 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} 71 id1 := HexID("0x00000000000000806ad9b61fa5ae014307ebdc964253adcd9f2c0a392aa11abc") 72 id2 := HexID("00000000000000806ad9b61fa5ae014307ebdc964253adcd9f2c0a392aa11abc") 73 74 if id1 != ref { 75 t.Errorf("wrong id1\ngot %v\nwant %v", id1[:], ref[:]) 76 } 77 if id2 != ref { 78 t.Errorf("wrong id2\ngot %v\nwant %v", id2[:], ref[:]) 79 } 80 } 81 82 func TestID_textEncoding(t *testing.T) { 83 ref := ID{ 84 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 85 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 86 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30, 87 0x31, 0x32, 88 } 89 hex := "0102030405060708091011121314151617181920212223242526272829303132" 90 91 text, err := ref.MarshalText() 92 if err != nil { 93 t.Fatal(err) 94 } 95 if !bytes.Equal(text, []byte(hex)) { 96 t.Fatalf("text encoding did not match\nexpected: %s\ngot: %s", hex, text) 97 } 98 99 id := new(ID) 100 if err := id.UnmarshalText(text); err != nil { 101 t.Fatal(err) 102 } 103 if *id != ref { 104 t.Fatalf("text decoding did not match\nexpected: %s\ngot: %s", ref, id) 105 } 106 } 107 108 func TestID_distcmp(t *testing.T) { 109 distcmpBig := func(target, a, b ID) int { 110 tbig := new(big.Int).SetBytes(target[:]) 111 abig := new(big.Int).SetBytes(a[:]) 112 bbig := new(big.Int).SetBytes(b[:]) 113 return new(big.Int).Xor(tbig, abig).Cmp(new(big.Int).Xor(tbig, bbig)) 114 } 115 if err := quick.CheckEqual(DistCmp, distcmpBig, nil); err != nil { 116 t.Error(err) 117 } 118 } 119 120 // The random tests is likely to miss the case where a and b are equal, 121 // this test checks it explicitly. 122 func TestID_distcmpEqual(t *testing.T) { 123 base := ID{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} 124 x := ID{15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0} 125 if DistCmp(base, x, x) != 0 { 126 t.Errorf("DistCmp(base, x, x) != 0") 127 } 128 } 129 130 func TestID_logdist(t *testing.T) { 131 logdistBig := func(a, b ID) int { 132 abig, bbig := new(big.Int).SetBytes(a[:]), new(big.Int).SetBytes(b[:]) 133 return new(big.Int).Xor(abig, bbig).BitLen() 134 } 135 if err := quick.CheckEqual(LogDist, logdistBig, nil); err != nil { 136 t.Error(err) 137 } 138 } 139 140 // The random tests is likely to miss the case where a and b are equal, 141 // this test checks it explicitly. 142 func TestID_logdistEqual(t *testing.T) { 143 x := ID{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} 144 if LogDist(x, x) != 0 { 145 t.Errorf("LogDist(x, x) != 0") 146 } 147 } 148 149 // Quorum 150 // 151 // test raft port in node detail 152 func TestNodeInfoForRaftPort(t *testing.T) { 153 node := NewV4Hostname( 154 hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), 155 "192.168.0.1", 156 30302, 157 30303, 158 2021, 159 ) 160 wantIP := enr.IPv4{192, 168, 0, 1} 161 wantUdp := 30303 162 wantTcp := 30302 163 wantRaftPort := 2021 164 assert.Equal(t, wantRaftPort, node.RaftPort(), "node raft port mismatch") 165 assert.Equal(t, net.IP(wantIP), node.IP(), "node ip mismatch") 166 assert.Equal(t, wantUdp, node.UDP(), "node UDP port mismatch") 167 assert.Equal(t, wantTcp, node.TCP(), "node TCP port mismatch") 168 169 } 170 171 // Quorum - test parsing url with hostname (if host is FQDN) 172 func TestNodeParseUrlWithHostnameForQuorum(t *testing.T) { 173 var url = "enode://ac6b1096ca56b9f6d004b779ae3728bf83f8e22453404cc3cef16a3d9b96608bc67c4b30db88e0a5a6c6390213f7acbe1153ff6d23ce57380104288ae19373ef@localhost:21000?discport=0&raftport=50401" 174 n, err := ParseV4(url) 175 if err != nil { 176 t.Errorf("parsing host failed %v", err) 177 } 178 assert.Equal(t, 50401, n.RaftPort()) 179 180 url = "enode://ac6b1096ca56b9f6d004b779ae3728bf83f8e22453404cc3cef16a3d9b96608bc67c4b30db88e0a5a6c6390213f7acbe1153ff6d23ce57380104288ae19373ef@localhost1:21000?discport=0&raftport=50401" 181 _, err = ParseV4(url) 182 if err != nil { 183 errMsg := err.Error() 184 hasError := strings.Contains(errMsg, "no such host") 185 186 assert.Equal(t, true, hasError, err.Error()) 187 } 188 } 189 190 // Quorum 191 // test Incomplete 192 func TestIncomplete(t *testing.T) { 193 var testCases = []struct { 194 n *Node 195 isIncomplete bool 196 }{ 197 { 198 n: NewV4( 199 hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), 200 net.IP{127, 0, 0, 1}, 201 52150, 202 52150, 203 ), 204 isIncomplete: false, 205 }, 206 { 207 n: NewV4(hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), 208 net.ParseIP("::"), 209 52150, 210 52150, 211 ), 212 isIncomplete: false, 213 }, 214 { 215 n: NewV4( 216 hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), 217 net.ParseIP("2001:db8:3c4d:15::abcd:ef12"), 218 52150, 219 52150, 220 ), 221 isIncomplete: false, 222 }, 223 { 224 n: NewV4( 225 hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), 226 nil, 227 52150, 228 52150, 229 ), 230 isIncomplete: true, 231 }, 232 { 233 n: NewV4Hostname( 234 hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), 235 "hostname", 236 52150, 237 52150, 238 50400, 239 ), 240 isIncomplete: false, 241 }, 242 { 243 n: NewV4Hostname( 244 hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), 245 "hostname", 246 52150, 247 52150, 248 0, 249 ), 250 isIncomplete: true, 251 }, 252 { 253 n: NewV4Hostname( 254 hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), 255 "", 256 52150, 257 52150, 258 50400, 259 ), 260 isIncomplete: true, 261 }, 262 } 263 264 for i, test := range testCases { 265 if test.n.Incomplete() != test.isIncomplete { 266 t.Errorf("test %d: Node.Incomplete() mismatch:\ngot: %v\nwant: %v", i, test.n.Incomplete(), test.isIncomplete) 267 } 268 } 269 }