github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/p2p/server_test.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 //版权所有2014 Go Ethereum作者 10 //此文件是Go以太坊库的一部分。 11 // 12 //Go-Ethereum库是免费软件:您可以重新分发它和/或修改 13 //根据GNU发布的较低通用公共许可证的条款 14 //自由软件基金会,或者许可证的第3版,或者 15 //(由您选择)任何更高版本。 16 // 17 //Go以太坊图书馆的发行目的是希望它会有用, 18 //但没有任何保证;甚至没有 19 //适销性或特定用途的适用性。见 20 //GNU较低的通用公共许可证,了解更多详细信息。 21 // 22 //你应该收到一份GNU较低级别的公共许可证副本 23 //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。 24 25 package p2p 26 27 import ( 28 "crypto/ecdsa" 29 "errors" 30 "math/rand" 31 "net" 32 "reflect" 33 "testing" 34 "time" 35 36 "github.com/ethereum/go-ethereum/crypto" 37 "github.com/ethereum/go-ethereum/crypto/sha3" 38 "github.com/ethereum/go-ethereum/log" 39 "github.com/ethereum/go-ethereum/p2p/discover" 40 ) 41 42 func init() { 43 //log.root().sethandler(log.lvlfilterhandler(log.lvlerror,log.streamhandler(os.stderr,log.terminalformat(false))) 44 } 45 46 type testTransport struct { 47 id discover.NodeID 48 *rlpx 49 50 closeErr error 51 } 52 53 func newTestTransport(id discover.NodeID, fd net.Conn) transport { 54 wrapped := newRLPX(fd).(*rlpx) 55 wrapped.rw = newRLPXFrameRW(fd, secrets{ 56 MAC: zero16, 57 AES: zero16, 58 IngressMAC: sha3.NewKeccak256(), 59 EgressMAC: sha3.NewKeccak256(), 60 }) 61 return &testTransport{id: id, rlpx: wrapped} 62 } 63 64 func (c *testTransport) doEncHandshake(prv *ecdsa.PrivateKey, dialDest *discover.Node) (discover.NodeID, error) { 65 return c.id, nil 66 } 67 68 func (c *testTransport) doProtoHandshake(our *protoHandshake) (*protoHandshake, error) { 69 return &protoHandshake{ID: c.id, Name: "test"}, nil 70 } 71 72 func (c *testTransport) close(err error) { 73 c.rlpx.fd.Close() 74 c.closeErr = err 75 } 76 77 func startTestServer(t *testing.T, id discover.NodeID, pf func(*Peer)) *Server { 78 config := Config{ 79 Name: "test", 80 MaxPeers: 10, 81 ListenAddr: "127.0.0.1:0", 82 PrivateKey: newkey(), 83 } 84 server := &Server{ 85 Config: config, 86 newPeerHook: pf, 87 newTransport: func(fd net.Conn) transport { return newTestTransport(id, fd) }, 88 } 89 if err := server.Start(); err != nil { 90 t.Fatalf("Could not start server: %v", err) 91 } 92 return server 93 } 94 95 func TestServerListen(t *testing.T) { 96 //启动测试服务器 97 connected := make(chan *Peer) 98 remid := randomID() 99 srv := startTestServer(t, remid, func(p *Peer) { 100 if p.ID() != remid { 101 t.Error("peer func called with wrong node id") 102 } 103 if p == nil { 104 t.Error("peer func called with nil conn") 105 } 106 connected <- p 107 }) 108 defer close(connected) 109 defer srv.Stop() 110 111 //拨号测试服务器 112 conn, err := net.DialTimeout("tcp", srv.ListenAddr, 5*time.Second) 113 if err != nil { 114 t.Fatalf("could not dial: %v", err) 115 } 116 defer conn.Close() 117 118 select { 119 case peer := <-connected: 120 if peer.LocalAddr().String() != conn.RemoteAddr().String() { 121 t.Errorf("peer started with wrong conn: got %v, want %v", 122 peer.LocalAddr(), conn.RemoteAddr()) 123 } 124 peers := srv.Peers() 125 if !reflect.DeepEqual(peers, []*Peer{peer}) { 126 t.Errorf("Peers mismatch: got %v, want %v", peers, []*Peer{peer}) 127 } 128 case <-time.After(1 * time.Second): 129 t.Error("server did not accept within one second") 130 } 131 } 132 133 func TestServerDial(t *testing.T) { 134 //运行一次性TCP服务器来处理连接。 135 listener, err := net.Listen("tcp", "127.0.0.1:0") 136 if err != nil { 137 t.Fatalf("could not setup listener: %v", err) 138 } 139 defer listener.Close() 140 accepted := make(chan net.Conn) 141 go func() { 142 conn, err := listener.Accept() 143 if err != nil { 144 t.Error("accept error:", err) 145 return 146 } 147 accepted <- conn 148 }() 149 150 //启动服务器 151 connected := make(chan *Peer) 152 remid := randomID() 153 srv := startTestServer(t, remid, func(p *Peer) { connected <- p }) 154 defer close(connected) 155 defer srv.Stop() 156 157 //告诉服务器连接 158 tcpAddr := listener.Addr().(*net.TCPAddr) 159 node := &discover.Node{ID: remid, IP: tcpAddr.IP, TCP: uint16(tcpAddr.Port)} 160 srv.AddPeer(node) 161 162 select { 163 case conn := <-accepted: 164 defer conn.Close() 165 166 select { 167 case peer := <-connected: 168 if peer.ID() != remid { 169 t.Errorf("peer has wrong id") 170 } 171 if peer.Name() != "test" { 172 t.Errorf("peer has wrong name") 173 } 174 if peer.RemoteAddr().String() != conn.LocalAddr().String() { 175 t.Errorf("peer started with wrong conn: got %v, want %v", 176 peer.RemoteAddr(), conn.LocalAddr()) 177 } 178 peers := srv.Peers() 179 if !reflect.DeepEqual(peers, []*Peer{peer}) { 180 t.Errorf("Peers mismatch: got %v, want %v", peers, []*Peer{peer}) 181 } 182 183 //测试addtrustedpeer/removetrustedpeer并更改可信标志 184 //尤其是在改变旗国的比赛条件下。 185 if peer := srv.Peers()[0]; peer.Info().Network.Trusted { 186 t.Errorf("peer is trusted prematurely: %v", peer) 187 } 188 done := make(chan bool) 189 go func() { 190 srv.AddTrustedPeer(node) 191 if peer := srv.Peers()[0]; !peer.Info().Network.Trusted { 192 t.Errorf("peer is not trusted after AddTrustedPeer: %v", peer) 193 } 194 srv.RemoveTrustedPeer(node) 195 if peer := srv.Peers()[0]; peer.Info().Network.Trusted { 196 t.Errorf("peer is trusted after RemoveTrustedPeer: %v", peer) 197 } 198 done <- true 199 }() 200 //触发潜在的竞争条件 201 peer = srv.Peers()[0] 202 _ = peer.Inbound() 203 _ = peer.Info() 204 <-done 205 case <-time.After(1 * time.Second): 206 t.Error("server did not launch peer within one second") 207 } 208 209 case <-time.After(1 * time.Second): 210 t.Error("server did not connect within one second") 211 } 212 } 213 214 //此测试检查由拨号状态生成的任务是否 215 //实际执行并调用taskdone。 216 func TestServerTaskScheduling(t *testing.T) { 217 var ( 218 done = make(chan *testTask) 219 quit, returned = make(chan struct{}), make(chan struct{}) 220 tc = 0 221 tg = taskgen{ 222 newFunc: func(running int, peers map[discover.NodeID]*Peer) []task { 223 tc++ 224 return []task{&testTask{index: tc - 1}} 225 }, 226 doneFunc: func(t task) { 227 select { 228 case done <- t.(*testTask): 229 case <-quit: 230 } 231 }, 232 } 233 ) 234 235 //此测试中的服务器没有实际运行 236 //因为我们只对Run的功能感兴趣。 237 srv := &Server{ 238 Config: Config{MaxPeers: 10}, 239 quit: make(chan struct{}), 240 ntab: fakeTable{}, 241 running: true, 242 log: log.New(), 243 } 244 srv.loopWG.Add(1) 245 go func() { 246 srv.run(tg) 247 close(returned) 248 }() 249 250 var gotdone []*testTask 251 for i := 0; i < 100; i++ { 252 gotdone = append(gotdone, <-done) 253 } 254 for i, task := range gotdone { 255 if task.index != i { 256 t.Errorf("task %d has wrong index, got %d", i, task.index) 257 break 258 } 259 if !task.called { 260 t.Errorf("task %d was not called", i) 261 break 262 } 263 } 264 265 close(quit) 266 srv.Stop() 267 select { 268 case <-returned: 269 case <-time.After(500 * time.Millisecond): 270 t.Error("Server.run did not return within 500ms") 271 } 272 } 273 274 //此测试检查服务器是否不删除任务, 275 //即使newtasks返回的任务数超过最大值。 276 func TestServerManyTasks(t *testing.T) { 277 alltasks := make([]task, 300) 278 for i := range alltasks { 279 alltasks[i] = &testTask{index: i} 280 } 281 282 var ( 283 srv = &Server{ 284 quit: make(chan struct{}), 285 ntab: fakeTable{}, 286 running: true, 287 log: log.New(), 288 } 289 done = make(chan *testTask) 290 start, end = 0, 0 291 ) 292 defer srv.Stop() 293 srv.loopWG.Add(1) 294 go srv.run(taskgen{ 295 newFunc: func(running int, peers map[discover.NodeID]*Peer) []task { 296 start, end = end, end+maxActiveDialTasks+10 297 if end > len(alltasks) { 298 end = len(alltasks) 299 } 300 return alltasks[start:end] 301 }, 302 doneFunc: func(tt task) { 303 done <- tt.(*testTask) 304 }, 305 }) 306 307 doneset := make(map[int]bool) 308 timeout := time.After(2 * time.Second) 309 for len(doneset) < len(alltasks) { 310 select { 311 case tt := <-done: 312 if doneset[tt.index] { 313 t.Errorf("task %d got done more than once", tt.index) 314 } else { 315 doneset[tt.index] = true 316 } 317 case <-timeout: 318 t.Errorf("%d of %d tasks got done within 2s", len(doneset), len(alltasks)) 319 for i := 0; i < len(alltasks); i++ { 320 if !doneset[i] { 321 t.Logf("task %d not done", i) 322 } 323 } 324 return 325 } 326 } 327 } 328 329 type taskgen struct { 330 newFunc func(running int, peers map[discover.NodeID]*Peer) []task 331 doneFunc func(task) 332 } 333 334 func (tg taskgen) newTasks(running int, peers map[discover.NodeID]*Peer, now time.Time) []task { 335 return tg.newFunc(running, peers) 336 } 337 func (tg taskgen) taskDone(t task, now time.Time) { 338 tg.doneFunc(t) 339 } 340 func (tg taskgen) addStatic(*discover.Node) { 341 } 342 func (tg taskgen) removeStatic(*discover.Node) { 343 } 344 345 type testTask struct { 346 index int 347 called bool 348 } 349 350 func (t *testTask) Do(srv *Server) { 351 t.called = true 352 } 353 354 //此测试检查连接是否断开 355 //当服务器处于 356 //按容量计算。仍应接受可信连接。 357 func TestServerAtCap(t *testing.T) { 358 trustedID := randomID() 359 srv := &Server{ 360 Config: Config{ 361 PrivateKey: newkey(), 362 MaxPeers: 10, 363 NoDial: true, 364 TrustedNodes: []*discover.Node{{ID: trustedID}}, 365 }, 366 } 367 if err := srv.Start(); err != nil { 368 t.Fatalf("could not start: %v", err) 369 } 370 defer srv.Stop() 371 372 newconn := func(id discover.NodeID) *conn { 373 fd, _ := net.Pipe() 374 tx := newTestTransport(id, fd) 375 return &conn{fd: fd, transport: tx, flags: inboundConn, id: id, cont: make(chan error)} 376 } 377 378 //注入一些连接以填充对等集。 379 for i := 0; i < 10; i++ { 380 c := newconn(randomID()) 381 if err := srv.checkpoint(c, srv.addpeer); err != nil { 382 t.Fatalf("could not add conn %d: %v", i, err) 383 } 384 } 385 //尝试插入不受信任的连接。 386 anotherID := randomID() 387 c := newconn(anotherID) 388 if err := srv.checkpoint(c, srv.posthandshake); err != DiscTooManyPeers { 389 t.Error("wrong error for insert:", err) 390 } 391 //尝试插入可信连接。 392 c = newconn(trustedID) 393 if err := srv.checkpoint(c, srv.posthandshake); err != nil { 394 t.Error("unexpected error for trusted conn @posthandshake:", err) 395 } 396 if !c.is(trustedConn) { 397 t.Error("Server did not set trusted flag") 398 } 399 400 //从受信任集中删除,然后重试 401 srv.RemoveTrustedPeer(&discover.Node{ID: trustedID}) 402 c = newconn(trustedID) 403 if err := srv.checkpoint(c, srv.posthandshake); err != DiscTooManyPeers { 404 t.Error("wrong error for insert:", err) 405 } 406 407 //将另一个ID添加到可信集,然后重试 408 srv.AddTrustedPeer(&discover.Node{ID: anotherID}) 409 c = newconn(anotherID) 410 if err := srv.checkpoint(c, srv.posthandshake); err != nil { 411 t.Error("unexpected error for trusted conn @posthandshake:", err) 412 } 413 if !c.is(trustedConn) { 414 t.Error("Server did not set trusted flag") 415 } 416 } 417 418 func TestServerPeerLimits(t *testing.T) { 419 srvkey := newkey() 420 421 clientid := randomID() 422 clientnode := &discover.Node{ID: clientid} 423 424 var tp *setupTransport = &setupTransport{ 425 id: clientid, 426 phs: &protoHandshake{ 427 ID: clientid, 428 //由于未匹配的大写字母而强制使用“discuselesspeer” 429 //大写:[]Cap Discard.Cap(), 430 }, 431 } 432 var flags connFlag = dynDialedConn 433 var dialDest *discover.Node = &discover.Node{ID: clientid} 434 435 srv := &Server{ 436 Config: Config{ 437 PrivateKey: srvkey, 438 MaxPeers: 0, 439 NoDial: true, 440 Protocols: []Protocol{discard}, 441 }, 442 newTransport: func(fd net.Conn) transport { return tp }, 443 log: log.New(), 444 } 445 if err := srv.Start(); err != nil { 446 t.Fatalf("couldn't start server: %v", err) 447 } 448 defer srv.Stop() 449 450 //检查服务器是否已满(maxpeers=0) 451 conn, _ := net.Pipe() 452 srv.SetupConn(conn, flags, dialDest) 453 if tp.closeErr != DiscTooManyPeers { 454 t.Errorf("unexpected close error: %q", tp.closeErr) 455 } 456 conn.Close() 457 458 srv.AddTrustedPeer(clientnode) 459 460 //检查服务器是否允许受信任的对等机(尽管已满)。 461 conn, _ = net.Pipe() 462 srv.SetupConn(conn, flags, dialDest) 463 if tp.closeErr == DiscTooManyPeers { 464 t.Errorf("failed to bypass MaxPeers with trusted node: %q", tp.closeErr) 465 } 466 467 if tp.closeErr != DiscUselessPeer { 468 t.Errorf("unexpected close error: %q", tp.closeErr) 469 } 470 conn.Close() 471 472 srv.RemoveTrustedPeer(clientnode) 473 474 //再次检查服务器是否已满。 475 conn, _ = net.Pipe() 476 srv.SetupConn(conn, flags, dialDest) 477 if tp.closeErr != DiscTooManyPeers { 478 t.Errorf("unexpected close error: %q", tp.closeErr) 479 } 480 conn.Close() 481 } 482 483 func TestServerSetupConn(t *testing.T) { 484 id := randomID() 485 srvkey := newkey() 486 srvid := discover.PubkeyID(&srvkey.PublicKey) 487 tests := []struct { 488 dontstart bool 489 tt *setupTransport 490 flags connFlag 491 dialDest *discover.Node 492 493 wantCloseErr error 494 wantCalls string 495 }{ 496 { 497 dontstart: true, 498 tt: &setupTransport{id: id}, 499 wantCalls: "close,", 500 wantCloseErr: errServerStopped, 501 }, 502 { 503 tt: &setupTransport{id: id, encHandshakeErr: errors.New("read error")}, 504 flags: inboundConn, 505 wantCalls: "doEncHandshake,close,", 506 wantCloseErr: errors.New("read error"), 507 }, 508 { 509 tt: &setupTransport{id: id}, 510 dialDest: &discover.Node{ID: randomID()}, 511 flags: dynDialedConn, 512 wantCalls: "doEncHandshake,close,", 513 wantCloseErr: DiscUnexpectedIdentity, 514 }, 515 { 516 tt: &setupTransport{id: id, phs: &protoHandshake{ID: randomID()}}, 517 dialDest: &discover.Node{ID: id}, 518 flags: dynDialedConn, 519 wantCalls: "doEncHandshake,doProtoHandshake,close,", 520 wantCloseErr: DiscUnexpectedIdentity, 521 }, 522 { 523 tt: &setupTransport{id: id, protoHandshakeErr: errors.New("foo")}, 524 dialDest: &discover.Node{ID: id}, 525 flags: dynDialedConn, 526 wantCalls: "doEncHandshake,doProtoHandshake,close,", 527 wantCloseErr: errors.New("foo"), 528 }, 529 { 530 tt: &setupTransport{id: srvid, phs: &protoHandshake{ID: srvid}}, 531 flags: inboundConn, 532 wantCalls: "doEncHandshake,close,", 533 wantCloseErr: DiscSelf, 534 }, 535 { 536 tt: &setupTransport{id: id, phs: &protoHandshake{ID: id}}, 537 flags: inboundConn, 538 wantCalls: "doEncHandshake,doProtoHandshake,close,", 539 wantCloseErr: DiscUselessPeer, 540 }, 541 } 542 543 for i, test := range tests { 544 srv := &Server{ 545 Config: Config{ 546 PrivateKey: srvkey, 547 MaxPeers: 10, 548 NoDial: true, 549 Protocols: []Protocol{discard}, 550 }, 551 newTransport: func(fd net.Conn) transport { return test.tt }, 552 log: log.New(), 553 } 554 if !test.dontstart { 555 if err := srv.Start(); err != nil { 556 t.Fatalf("couldn't start server: %v", err) 557 } 558 } 559 p1, _ := net.Pipe() 560 srv.SetupConn(p1, test.flags, test.dialDest) 561 if !reflect.DeepEqual(test.tt.closeErr, test.wantCloseErr) { 562 t.Errorf("test %d: close error mismatch: got %q, want %q", i, test.tt.closeErr, test.wantCloseErr) 563 } 564 if test.tt.calls != test.wantCalls { 565 t.Errorf("test %d: calls mismatch: got %q, want %q", i, test.tt.calls, test.wantCalls) 566 } 567 } 568 } 569 570 type setupTransport struct { 571 id discover.NodeID 572 encHandshakeErr error 573 574 phs *protoHandshake 575 protoHandshakeErr error 576 577 calls string 578 closeErr error 579 } 580 581 func (c *setupTransport) doEncHandshake(prv *ecdsa.PrivateKey, dialDest *discover.Node) (discover.NodeID, error) { 582 c.calls += "doEncHandshake," 583 return c.id, c.encHandshakeErr 584 } 585 func (c *setupTransport) doProtoHandshake(our *protoHandshake) (*protoHandshake, error) { 586 c.calls += "doProtoHandshake," 587 if c.protoHandshakeErr != nil { 588 return nil, c.protoHandshakeErr 589 } 590 return c.phs, nil 591 } 592 func (c *setupTransport) close(err error) { 593 c.calls += "close," 594 c.closeErr = err 595 } 596 597 //SetupConn不应写入/读取连接。 598 func (c *setupTransport) WriteMsg(Msg) error { 599 panic("WriteMsg called on setupTransport") 600 } 601 func (c *setupTransport) ReadMsg() (Msg, error) { 602 panic("ReadMsg called on setupTransport") 603 } 604 605 func newkey() *ecdsa.PrivateKey { 606 key, err := crypto.GenerateKey() 607 if err != nil { 608 panic("couldn't generate key: " + err.Error()) 609 } 610 return key 611 } 612 613 func randomID() (id discover.NodeID) { 614 for i := range id { 615 id[i] = byte(rand.Intn(255)) 616 } 617 return id 618 }