github.com/zjj1991/quorum@v0.0.0-20190524123704-ae4b0a1e1a19/p2p/enode/urlv4_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 "crypto/ecdsa" 22 "math/big" 23 "net" 24 "reflect" 25 "strings" 26 "testing" 27 "testing/quick" 28 ) 29 30 var parseNodeTests = []struct { 31 rawurl string 32 wantError string 33 wantResult *Node 34 }{ 35 { 36 rawurl: "http://foobar", 37 wantError: `invalid URL scheme, want "enode"`, 38 }, 39 { 40 rawurl: "enode://01010101@123.124.125.126:3", 41 wantError: `invalid node ID (wrong length, want 128 hex chars)`, 42 }, 43 // Complete nodes with IP address. 44 { 45 rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@hostname:3", 46 wantError: `invalid IP address`, 47 }, 48 { 49 rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@127.0.0.1:foo", 50 wantError: `invalid port`, 51 }, 52 { 53 rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@127.0.0.1:3?discport=foo", 54 wantError: `invalid discport in query`, 55 }, 56 { 57 rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@127.0.0.1:52150", 58 wantResult: NewV4( 59 hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), 60 net.IP{0x7f, 0x0, 0x0, 0x1}, 61 52150, 62 52150, 63 0, 64 ), 65 }, 66 { 67 rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@[::]:52150", 68 wantResult: NewV4( 69 hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), 70 net.ParseIP("::"), 71 52150, 72 52150, 73 0, 74 ), 75 }, 76 { 77 rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@[2001:db8:3c4d:15::abcd:ef12]:52150", 78 wantResult: NewV4( 79 hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), 80 net.ParseIP("2001:db8:3c4d:15::abcd:ef12"), 81 52150, 82 52150, 83 0, 84 ), 85 }, 86 { 87 rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@127.0.0.1:52150?discport=22334", 88 wantResult: NewV4( 89 hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), 90 net.IP{0x7f, 0x0, 0x0, 0x1}, 91 52150, 92 22334, 93 0, 94 ), 95 }, 96 // Incomplete nodes with no address. 97 { 98 rawurl: "1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439", 99 wantResult: NewV4( 100 hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), 101 nil, 0, 0, 0, 102 ), 103 }, 104 { 105 rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439", 106 wantResult: NewV4( 107 hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), 108 nil, 0, 0, 0, 109 ), 110 }, 111 // Invalid URLs 112 { 113 rawurl: "01010101", 114 wantError: `invalid node ID (wrong length, want 128 hex chars)`, 115 }, 116 { 117 rawurl: "enode://01010101", 118 wantError: `invalid node ID (wrong length, want 128 hex chars)`, 119 }, 120 { 121 // This test checks that errors from url.Parse are handled. 122 rawurl: "://foo", 123 wantError: `parse ://foo: missing protocol scheme`, 124 }, 125 } 126 127 func hexPubkey(h string) *ecdsa.PublicKey { 128 k, err := parsePubkey(h) 129 if err != nil { 130 panic(err) 131 } 132 return k 133 } 134 135 func TestParseNode(t *testing.T) { 136 for _, test := range parseNodeTests { 137 n, err := ParseV4(test.rawurl) 138 if test.wantError != "" { 139 if err == nil { 140 t.Errorf("test %q:\n got nil error, expected %#q", test.rawurl, test.wantError) 141 continue 142 } else if err.Error() != test.wantError { 143 t.Errorf("test %q:\n got error %#q, expected %#q", test.rawurl, err.Error(), test.wantError) 144 continue 145 } 146 } else { 147 if err != nil { 148 t.Errorf("test %q:\n unexpected error: %v", test.rawurl, err) 149 continue 150 } 151 if !reflect.DeepEqual(n, test.wantResult) { 152 t.Errorf("test %q:\n result mismatch:\ngot: %#v\nwant: %#v", test.rawurl, n, test.wantResult) 153 } 154 } 155 } 156 } 157 158 func TestNodeString(t *testing.T) { 159 for i, test := range parseNodeTests { 160 if test.wantError == "" && strings.HasPrefix(test.rawurl, "enode://") { 161 str := test.wantResult.String() 162 if str != test.rawurl { 163 t.Errorf("test %d: Node.String() mismatch:\ngot: %s\nwant: %s", i, str, test.rawurl) 164 } 165 } 166 } 167 } 168 169 func TestHexID(t *testing.T) { 170 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} 171 id1 := HexID("0x00000000000000806ad9b61fa5ae014307ebdc964253adcd9f2c0a392aa11abc") 172 id2 := HexID("00000000000000806ad9b61fa5ae014307ebdc964253adcd9f2c0a392aa11abc") 173 174 if id1 != ref { 175 t.Errorf("wrong id1\ngot %v\nwant %v", id1[:], ref[:]) 176 } 177 if id2 != ref { 178 t.Errorf("wrong id2\ngot %v\nwant %v", id2[:], ref[:]) 179 } 180 } 181 182 func TestID_textEncoding(t *testing.T) { 183 ref := ID{ 184 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 185 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 186 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30, 187 0x31, 0x32, 188 } 189 hex := "0102030405060708091011121314151617181920212223242526272829303132" 190 191 text, err := ref.MarshalText() 192 if err != nil { 193 t.Fatal(err) 194 } 195 if !bytes.Equal(text, []byte(hex)) { 196 t.Fatalf("text encoding did not match\nexpected: %s\ngot: %s", hex, text) 197 } 198 199 id := new(ID) 200 if err := id.UnmarshalText(text); err != nil { 201 t.Fatal(err) 202 } 203 if *id != ref { 204 t.Fatalf("text decoding did not match\nexpected: %s\ngot: %s", ref, id) 205 } 206 } 207 208 func TestNodeID_distcmp(t *testing.T) { 209 distcmpBig := func(target, a, b ID) int { 210 tbig := new(big.Int).SetBytes(target[:]) 211 abig := new(big.Int).SetBytes(a[:]) 212 bbig := new(big.Int).SetBytes(b[:]) 213 return new(big.Int).Xor(tbig, abig).Cmp(new(big.Int).Xor(tbig, bbig)) 214 } 215 if err := quick.CheckEqual(DistCmp, distcmpBig, nil); err != nil { 216 t.Error(err) 217 } 218 } 219 220 // The random tests is likely to miss the case where a and b are equal, 221 // this test checks it explicitly. 222 func TestNodeID_distcmpEqual(t *testing.T) { 223 base := ID{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} 224 x := ID{15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0} 225 if DistCmp(base, x, x) != 0 { 226 t.Errorf("DistCmp(base, x, x) != 0") 227 } 228 } 229 230 func TestNodeID_logdist(t *testing.T) { 231 logdistBig := func(a, b ID) int { 232 abig, bbig := new(big.Int).SetBytes(a[:]), new(big.Int).SetBytes(b[:]) 233 return new(big.Int).Xor(abig, bbig).BitLen() 234 } 235 if err := quick.CheckEqual(LogDist, logdistBig, nil); err != nil { 236 t.Error(err) 237 } 238 } 239 240 // The random tests is likely to miss the case where a and b are equal, 241 // this test checks it explicitly. 242 func TestNodeID_logdistEqual(t *testing.T) { 243 x := ID{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} 244 if LogDist(x, x) != 0 { 245 t.Errorf("LogDist(x, x) != 0") 246 } 247 }