github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/p2p/enode/urlv4_test.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 19:16:41</date> 10 //</624450104639623168> 11 12 13 package enode 14 15 import ( 16 "bytes" 17 "crypto/ecdsa" 18 "math/big" 19 "net" 20 "reflect" 21 "strings" 22 "testing" 23 "testing/quick" 24 ) 25 26 var parseNodeTests = []struct { 27 rawurl string 28 wantError string 29 wantResult *Node 30 }{ 31 { 32 rawurl: "http://“福巴” 33 wantError: `invalid URL scheme, want "enode"`, 34 }, 35 { 36 rawurl: "enode://01010101@123.124.125.126:3“, 37 wantError: `invalid node ID (wrong length, want 128 hex chars)`, 38 }, 39 //使用IP地址完成节点。 40 { 41 rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6c1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@hostname:3“, 42 wantError: `invalid IP address`, 43 }, 44 { 45 rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6c1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@127.0.0.1:foo“, 46 wantError: `invalid port`, 47 }, 48 { 49 rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6c1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@127.0.0.1:3?迪斯科= 50 wantError: `invalid discport in query`, 51 }, 52 { 53 rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6c1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@127.0.0.1:52150“, 54 wantResult: NewV4( 55 hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), 56 net.IP{0x7f, 0x0, 0x0, 0x1}, 57 52150, 58 52150, 59 ), 60 }, 61 { 62 rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6c1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@[::]:52150“, 63 wantResult: NewV4( 64 hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), 65 net.ParseIP("::"), 66 52150, 67 52150, 68 ), 69 }, 70 { 71 rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6c1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@[2001:db8:3c4d:15::abcd:ef12]:52150“, 72 wantResult: NewV4( 73 hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), 74 net.ParseIP("2001:db8:3c4d:15::abcd:ef12"), 75 52150, 76 52150, 77 ), 78 }, 79 { 80 rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6c1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439@127.0.0.1:52150?discport=22334“, 81 wantResult: NewV4( 82 hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), 83 net.IP{0x7f, 0x0, 0x0, 0x1}, 84 52150, 85 22334, 86 ), 87 }, 88 //没有地址的不完整节点。 89 { 90 rawurl: "1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439", 91 wantResult: NewV4( 92 hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), 93 nil, 0, 0, 94 ), 95 }, 96 { 97 rawurl: "enode://1dd9d65c4552b5eb43d5ad55a2ee3f56c6c6c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439“, 98 wantResult: NewV4( 99 hexPubkey("1dd9d65c4552b5eb43d5ad55a2ee3f56c6cbc1c64a5c8d659f51fcd51bace24351232b8d7821617d2b29b54b81cdefb9b3e9c37d7fd5f63270bcc9e1a6f6a439"), 100 nil, 0, 0, 101 ), 102 }, 103 //无效网址 104 { 105 rawurl: "01010101", 106 wantError: `invalid node ID (wrong length, want 128 hex chars)`, 107 }, 108 { 109 rawurl: "enode://01010101“, 110 wantError: `invalid node ID (wrong length, want 128 hex chars)`, 111 }, 112 { 113 //此测试检查是否处理了URL.Parse中的错误。 114 rawurl: "://“,” 115 wantError: `parse ://foo:缺少协议方案`, 116 }, 117 } 118 119 func hexPubkey(h string) *ecdsa.PublicKey { 120 k, err := parsePubkey(h) 121 if err != nil { 122 panic(err) 123 } 124 return k 125 } 126 127 func TestParseNode(t *testing.T) { 128 for _, test := range parseNodeTests { 129 n, err := ParseV4(test.rawurl) 130 if test.wantError != "" { 131 if err == nil { 132 t.Errorf("test %q:\n got nil error, expected %#q", test.rawurl, test.wantError) 133 continue 134 } else if err.Error() != test.wantError { 135 t.Errorf("test %q:\n got error %#q, expected %#q", test.rawurl, err.Error(), test.wantError) 136 continue 137 } 138 } else { 139 if err != nil { 140 t.Errorf("test %q:\n unexpected error: %v", test.rawurl, err) 141 continue 142 } 143 if !reflect.DeepEqual(n, test.wantResult) { 144 t.Errorf("test %q:\n result mismatch:\ngot: %#v\nwant: %#v", test.rawurl, n, test.wantResult) 145 } 146 } 147 } 148 } 149 150 func TestNodeString(t *testing.T) { 151 for i, test := range parseNodeTests { 152 if test.wantError == "" && strings.HasPrefix(test.rawurl, "enode://“”{ 153 str := test.wantResult.String() 154 if str != test.rawurl { 155 t.Errorf("test %d: Node.String() mismatch:\ngot: %s\nwant: %s", i, str, test.rawurl) 156 } 157 } 158 } 159 } 160 161 func TestHexID(t *testing.T) { 162 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} 163 id1 := HexID("0x00000000000000806ad9b61fa5ae014307ebdc964253adcd9f2c0a392aa11abc") 164 id2 := HexID("00000000000000806ad9b61fa5ae014307ebdc964253adcd9f2c0a392aa11abc") 165 166 if id1 != ref { 167 t.Errorf("wrong id1\ngot %v\nwant %v", id1[:], ref[:]) 168 } 169 if id2 != ref { 170 t.Errorf("wrong id2\ngot %v\nwant %v", id2[:], ref[:]) 171 } 172 } 173 174 func TestID_textEncoding(t *testing.T) { 175 ref := ID{ 176 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x10, 177 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x20, 178 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30, 179 0x31, 0x32, 180 } 181 hex := "0102030405060708091011121314151617181920212223242526272829303132" 182 183 text, err := ref.MarshalText() 184 if err != nil { 185 t.Fatal(err) 186 } 187 if !bytes.Equal(text, []byte(hex)) { 188 t.Fatalf("text encoding did not match\nexpected: %s\ngot: %s", hex, text) 189 } 190 191 id := new(ID) 192 if err := id.UnmarshalText(text); err != nil { 193 t.Fatal(err) 194 } 195 if *id != ref { 196 t.Fatalf("text decoding did not match\nexpected: %s\ngot: %s", ref, id) 197 } 198 } 199 200 func TestNodeID_distcmp(t *testing.T) { 201 distcmpBig := func(target, a, b ID) int { 202 tbig := new(big.Int).SetBytes(target[:]) 203 abig := new(big.Int).SetBytes(a[:]) 204 bbig := new(big.Int).SetBytes(b[:]) 205 return new(big.Int).Xor(tbig, abig).Cmp(new(big.Int).Xor(tbig, bbig)) 206 } 207 if err := quick.CheckEqual(DistCmp, distcmpBig, nil); err != nil { 208 t.Error(err) 209 } 210 } 211 212 //随机测试可能会错过A和B相等的情况, 213 //这个测试明确地检查它。 214 func TestNodeID_distcmpEqual(t *testing.T) { 215 base := ID{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} 216 x := ID{15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0} 217 if DistCmp(base, x, x) != 0 { 218 t.Errorf("DistCmp(base, x, x) != 0") 219 } 220 } 221 222 func TestNodeID_logdist(t *testing.T) { 223 logdistBig := func(a, b ID) int { 224 abig, bbig := new(big.Int).SetBytes(a[:]), new(big.Int).SetBytes(b[:]) 225 return new(big.Int).Xor(abig, bbig).BitLen() 226 } 227 if err := quick.CheckEqual(LogDist, logdistBig, nil); err != nil { 228 t.Error(err) 229 } 230 } 231 232 //随机测试可能会错过A和B相等的情况, 233 //这个测试明确地检查它。 234 func TestNodeID_logdistEqual(t *testing.T) { 235 x := ID{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} 236 if LogDist(x, x) != 0 { 237 t.Errorf("LogDist(x, x) != 0") 238 } 239 } 240