github.com/Unheilbar/quorum@v1.0.0/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/ethereum/go-ethereum/p2p/enr" 30 "github.com/ethereum/go-ethereum/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 // Quorum - test parsing url with hostname (if host is FQDN) 171 func TestNodeParseUrlWithHostnameForQuorum(t *testing.T) { 172 var url = "enode://ac6b1096ca56b9f6d004b779ae3728bf83f8e22453404cc3cef16a3d9b96608bc67c4b30db88e0a5a6c6390213f7acbe1153ff6d23ce57380104288ae19373ef@localhost:21000?discport=0&raftport=50401" 173 n, err := ParseV4(url) 174 if err != nil { 175 t.Errorf("parsing host failed %v", err) 176 } 177 assert.Equal(t, 50401, n.RaftPort()) 178 179 url = "enode://ac6b1096ca56b9f6d004b779ae3728bf83f8e22453404cc3cef16a3d9b96608bc67c4b30db88e0a5a6c6390213f7acbe1153ff6d23ce57380104288ae19373ef@localhost1:21000?discport=0&raftport=50401" 180 _, err = ParseV4(url) 181 if err != nil { 182 errMsg := err.Error() 183 hasError := strings.Contains(errMsg, "no such host") 184 185 assert.Equal(t, true, hasError, err.Error()) 186 } 187 } 188 189 // Quorum 190 // test Incomplete 191 func TestIncomplete(t *testing.T) { 192 var testCases = []struct { 193 n *Node 194 isIncomplete bool 195 }{ 196 { 197 n: NewV4( 198 hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), 199 net.IP{127, 0, 0, 1}, 200 52150, 201 52150, 202 ), 203 isIncomplete: false, 204 }, 205 { 206 n: NewV4(hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), 207 net.ParseIP("::"), 208 52150, 209 52150, 210 ), 211 isIncomplete: false, 212 }, 213 { 214 n: NewV4( 215 hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), 216 net.ParseIP("2001:db8:3c4d:15::abcd:ef12"), 217 52150, 218 52150, 219 ), 220 isIncomplete: false, 221 }, 222 { 223 n: NewV4( 224 hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), 225 nil, 226 52150, 227 52150, 228 ), 229 isIncomplete: true, 230 }, 231 { 232 n: NewV4Hostname( 233 hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), 234 "hostname", 235 52150, 236 52150, 237 50400, 238 ), 239 isIncomplete: false, 240 }, 241 { 242 n: NewV4Hostname( 243 hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), 244 "hostname", 245 52150, 246 52150, 247 0, 248 ), 249 isIncomplete: true, 250 }, 251 { 252 n: NewV4Hostname( 253 hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), 254 "", 255 52150, 256 52150, 257 50400, 258 ), 259 isIncomplete: true, 260 }, 261 } 262 263 for i, test := range testCases { 264 if test.n.Incomplete() != test.isIncomplete { 265 t.Errorf("test %d: Node.Incomplete() mismatch:\ngot: %v\nwant: %v", i, test.n.Incomplete(), test.isIncomplete) 266 } 267 } 268 }