github.com/aigarnetwork/aigar@v0.0.0-20191115204914-d59a6eb70f8e/p2p/enode/urlv4_test.go (about) 1 // Copyright 2018 The go-ethereum Authors 2 // Copyright 2019 The go-aigar Authors 3 // This file is part of the go-aigar library. 4 // 5 // The go-aigar library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The go-aigar library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the go-aigar library. If not, see <http://www.gnu.org/licenses/>. 17 18 package enode 19 20 import ( 21 "crypto/ecdsa" 22 "errors" 23 "net" 24 "reflect" 25 "strings" 26 "testing" 27 28 "github.com/AigarNetwork/aigar/crypto" 29 "github.com/AigarNetwork/aigar/p2p/enr" 30 ) 31 32 func init() { 33 lookupIPFunc = func(name string) ([]net.IP, error) { 34 if name == "node.example.org" { 35 return []net.IP{{33, 44, 55, 66}}, nil 36 } 37 return nil, errors.New("no such host") 38 } 39 } 40 41 var parseNodeTests = []struct { 42 input string 43 wantError string 44 wantResult *Node 45 }{ 46 // Records 47 { 48 input: "enr:-IS4QGrdq0ugARp5T2BZ41TrZOqLc_oKvZoPuZP5--anqWE_J-Tucc1xgkOL7qXl0puJgT7qc2KSvcupc4NCb0nr4tdjgmlkgnY0gmlwhH8AAAGJc2VjcDI1NmsxoQM6UUF2Rm-oFe1IH_rQkRCi00T2ybeMHRSvw1HDpRvjPYN1ZHCCdl8", 49 wantResult: func() *Node { 50 testKey, _ := crypto.HexToECDSA("45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8") 51 var r enr.Record 52 r.Set(enr.IP{127, 0, 0, 1}) 53 r.Set(enr.UDP(30303)) 54 r.SetSeq(99) 55 SignV4(&r, testKey) 56 n, _ := New(ValidSchemes, &r) 57 return n 58 }(), 59 }, 60 // Invalid Records 61 { 62 input: "enr:", 63 wantError: "EOF", // could be nicer 64 }, 65 { 66 input: "enr:x", 67 wantError: "illegal base64 data at input byte 0", 68 }, 69 { 70 input: "enr:-EmGZm9vYmFyY4JpZIJ2NIJpcIR_AAABiXNlY3AyNTZrMaEDOlFBdkZvqBXtSB_60JEQotNE9sm3jB0Ur8NRw6Ub4z2DdWRwgnZf", 71 wantError: enr.ErrInvalidSig.Error(), 72 }, 73 // Complete node URLs with IP address and ports 74 { 75 input: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@invalid.:3", 76 wantError: `no such host`, 77 }, 78 { 79 input: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@127.0.0.1:foo", 80 wantError: `invalid port`, 81 }, 82 { 83 input: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@127.0.0.1:3?discport=foo", 84 wantError: `invalid discport in query`, 85 }, 86 { 87 input: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@127.0.0.1:52150", 88 wantResult: NewV4( 89 hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), 90 net.IP{127, 0, 0, 1}, 91 52150, 92 52150, 93 ), 94 }, 95 { 96 input: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@[::]:52150", 97 wantResult: NewV4( 98 hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), 99 net.ParseIP("::"), 100 52150, 101 52150, 102 ), 103 }, 104 { 105 input: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@[2001:db8:3c4d:15::abcd:ef12]:52150", 106 wantResult: NewV4( 107 hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), 108 net.ParseIP("2001:db8:3c4d:15::abcd:ef12"), 109 52150, 110 52150, 111 ), 112 }, 113 { 114 input: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@127.0.0.1:52150?discport=22334", 115 wantResult: NewV4( 116 hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), 117 net.IP{0x7f, 0x0, 0x0, 0x1}, 118 52150, 119 22334, 120 ), 121 }, 122 // Incomplete node URLs with no address 123 { 124 input: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439", 125 wantResult: NewV4( 126 hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), 127 nil, 0, 0, 128 ), 129 }, 130 // Invalid URLs 131 { 132 input: "", 133 wantError: errMissingPrefix.Error(), 134 }, 135 { 136 input: "1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439", 137 wantError: errMissingPrefix.Error(), 138 }, 139 { 140 input: "01010101", 141 wantError: errMissingPrefix.Error(), 142 }, 143 { 144 input: "enode://01010101@123.124.125.126:3", 145 wantError: `invalid public key (wrong length, want 128 hex chars)`, 146 }, 147 { 148 input: "enode://01010101", 149 wantError: `invalid public key (wrong length, want 128 hex chars)`, 150 }, 151 { 152 input: "http://foobar", 153 wantError: errMissingPrefix.Error(), 154 }, 155 { 156 input: "://foo", 157 wantError: errMissingPrefix.Error(), 158 }, 159 } 160 161 func hexPubkey(h string) *ecdsa.PublicKey { 162 k, err := parsePubkey(h) 163 if err != nil { 164 panic(err) 165 } 166 return k 167 } 168 169 func TestParseNode(t *testing.T) { 170 for _, test := range parseNodeTests { 171 n, err := Parse(ValidSchemes, test.input) 172 if test.wantError != "" { 173 if err == nil { 174 t.Errorf("test %q:\n got nil error, expected %#q", test.input, test.wantError) 175 continue 176 } else if !strings.Contains(err.Error(), test.wantError) { 177 t.Errorf("test %q:\n got error %#q, expected %#q", test.input, err.Error(), test.wantError) 178 continue 179 } 180 } else { 181 if err != nil { 182 t.Errorf("test %q:\n unexpected error: %v", test.input, err) 183 continue 184 } 185 if !reflect.DeepEqual(n, test.wantResult) { 186 t.Errorf("test %q:\n result mismatch:\ngot: %#v\nwant: %#v", test.input, n, test.wantResult) 187 } 188 } 189 } 190 } 191 192 func TestNodeString(t *testing.T) { 193 for i, test := range parseNodeTests { 194 if test.wantError == "" && strings.HasPrefix(test.input, "enode://") { 195 str := test.wantResult.String() 196 if str != test.input { 197 t.Errorf("test %d: Node.String() mismatch:\ngot: %s\nwant: %s", i, str, test.input) 198 } 199 } 200 } 201 }