github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/p2p/server.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 //</624450106418008064> 11 12 13 //包P2P实现以太坊P2P网络协议。 14 package p2p 15 16 import ( 17 "bytes" 18 "crypto/ecdsa" 19 "encoding/hex" 20 "errors" 21 "net" 22 "sort" 23 "sync" 24 "sync/atomic" 25 "time" 26 27 "github.com/ethereum/go-ethereum/common" 28 "github.com/ethereum/go-ethereum/common/mclock" 29 "github.com/ethereum/go-ethereum/crypto" 30 "github.com/ethereum/go-ethereum/event" 31 "github.com/ethereum/go-ethereum/log" 32 "github.com/ethereum/go-ethereum/p2p/discover" 33 "github.com/ethereum/go-ethereum/p2p/discv5" 34 "github.com/ethereum/go-ethereum/p2p/enode" 35 "github.com/ethereum/go-ethereum/p2p/enr" 36 "github.com/ethereum/go-ethereum/p2p/nat" 37 "github.com/ethereum/go-ethereum/p2p/netutil" 38 "github.com/ethereum/go-ethereum/rlp" 39 ) 40 41 const ( 42 defaultDialTimeout = 15 * time.Second 43 44 //连接默认值。 45 maxActiveDialTasks = 16 46 defaultMaxPendingPeers = 50 47 defaultDialRatio = 3 48 49 //读取完整邮件所允许的最长时间。 50 //这实际上是连接可以空闲的时间量。 51 frameReadTimeout = 30 * time.Second 52 53 //写入完整消息所允许的最长时间。 54 frameWriteTimeout = 20 * time.Second 55 ) 56 57 var errServerStopped = errors.New("server stopped") 58 59 //配置保留服务器选项。 60 type Config struct { 61 //此字段必须设置为有效的secp256k1私钥。 62 PrivateKey *ecdsa.PrivateKey `toml:"-"` 63 64 //MaxPeers是可以 65 //有联系的。它必须大于零。 66 MaxPeers int 67 68 //MaxPendingPeers是在 69 //握手阶段,分别为入站和出站连接计数。 70 //零默认为预设值。 71 MaxPendingPeers int `toml:",omitempty"` 72 73 //DialRatio控制入站与拨入连接的比率。 74 //示例:拨号比率2允许拨1/2的连接。 75 //将DialRatio设置为零将默认为3。 76 DialRatio int `toml:",omitempty"` 77 78 //nodiscovery可用于禁用对等发现机制。 79 //禁用对于协议调试(手动拓扑)很有用。 80 NoDiscovery bool 81 82 //Discoveryv5指定新的基于主题发现的v5发现 83 //是否启动协议。 84 DiscoveryV5 bool `toml:",omitempty"` 85 86 //名称设置此服务器的节点名称。 87 //使用common.makename创建遵循现有约定的名称。 88 Name string `toml:"-"` 89 90 //bootstrapnodes用于建立连接 91 //与网络的其他部分。 92 BootstrapNodes []*enode.Node 93 94 //bootstrapnodesv5用于建立连接 95 //与网络的其余部分一起使用v5发现 96 //协议。 97 BootstrapNodesV5 []*discv5.Node `toml:",omitempty"` 98 99 //静态节点用作预先配置的连接,这些连接总是 100 //在断开时保持并重新连接。 101 StaticNodes []*enode.Node 102 103 //受信任节点用作预先配置的连接,这些连接总是 104 //允许连接,甚至高于对等限制。 105 TrustedNodes []*enode.Node 106 107 //连接可以限制到某些IP网络。 108 //如果此选项设置为非nil值,则仅主机与 109 //考虑列表中包含的IP网络。 110 NetRestrict *netutil.Netlist `toml:",omitempty"` 111 112 //nodedatabase是包含以前看到的 113 //网络中的活动节点。 114 NodeDatabase string `toml:",omitempty"` 115 116 //协议应包含支持的协议 117 //由服务器。为启动匹配协议 118 //每个对等体。 119 Protocols []Protocol `toml:"-"` 120 121 //如果listenaddr设置为非nil地址,则服务器 122 //将侦听传入的连接。 123 // 124 //如果端口为零,操作系统将选择一个端口。这个 125 //当 126 //服务器已启动。 127 ListenAddr string 128 129 //如果设置为非零值,则指定的NAT端口映射器 130 //用于使侦听端口对 131 //互联网。 132 NAT nat.Interface `toml:",omitempty"` 133 134 //如果拨号程序设置为非零值,则指定的拨号程序 135 //用于拨号出站对等连接。 136 Dialer NodeDialer `toml:"-"` 137 138 //如果nodial为真,服务器将不会拨任何对等机。 139 NoDial bool `toml:",omitempty"` 140 141 //如果设置了EnableMsgeEvents,则服务器将发出PeerEvents 142 //无论何时向对等端发送或从对等端接收消息 143 EnableMsgEvents bool 144 145 //logger是用于p2p.server的自定义记录器。 146 Logger log.Logger `toml:",omitempty"` 147 } 148 149 //服务器管理所有对等连接。 150 type Server struct { 151 //服务器运行时不能修改配置字段。 152 Config 153 154 //测试用挂钩。这些是有用的,因为我们可以抑制 155 //整个协议栈。 156 newTransport func(net.Conn) transport 157 newPeerHook func(*Peer) 158 159 lock sync.Mutex //保护运行 160 running bool 161 162 nodedb *enode.DB 163 localnode *enode.LocalNode 164 ntab discoverTable 165 listener net.Listener 166 ourHandshake *protoHandshake 167 lastLookup time.Time 168 DiscV5 *discv5.Network 169 170 //这些是为对等机,对等机计数(而不是其他任何东西)。 171 peerOp chan peerOpFunc 172 peerOpDone chan struct{} 173 174 quit chan struct{} 175 addstatic chan *enode.Node 176 removestatic chan *enode.Node 177 addtrusted chan *enode.Node 178 removetrusted chan *enode.Node 179 posthandshake chan *conn 180 addpeer chan *conn 181 delpeer chan peerDrop 182 loopWG sync.WaitGroup //循环,listenloop 183 peerFeed event.Feed 184 log log.Logger 185 } 186 187 type peerOpFunc func(map[enode.ID]*Peer) 188 189 type peerDrop struct { 190 *Peer 191 err error 192 requested bool //如果对等方发出信号,则为真 193 } 194 195 type connFlag int32 196 197 const ( 198 dynDialedConn connFlag = 1 << iota 199 staticDialedConn 200 inboundConn 201 trustedConn 202 ) 203 204 // 205 //在两次握手中。 206 type conn struct { 207 fd net.Conn 208 transport 209 node *enode.Node 210 flags connFlag 211 cont chan error //运行循环使用cont向setupconn发送错误信号。 212 caps []Cap //协议握手后有效 213 name string //协议握手后有效 214 } 215 216 type transport interface { 217 //两人握手。 218 doEncHandshake(prv *ecdsa.PrivateKey, dialDest *ecdsa.PublicKey) (*ecdsa.PublicKey, error) 219 doProtoHandshake(our *protoHandshake) (*protoHandshake, error) 220 //msgreadwriter只能在加密后使用 221 //握手已完成。代码使用conn.id跟踪 222 //通过在加密握手后将其设置为非零值。 223 MsgReadWriter 224 //传输必须提供close,因为我们在 225 //测试。关闭实际网络连接不起作用 226 //这些测试中的任何内容,因为msgpipe不使用它。 227 close(err error) 228 } 229 230 func (c *conn) String() string { 231 s := c.flags.String() 232 if (c.node.ID() != enode.ID{}) { 233 s += " " + c.node.ID().String() 234 } 235 s += " " + c.fd.RemoteAddr().String() 236 return s 237 } 238 239 func (f connFlag) String() string { 240 s := "" 241 if f&trustedConn != 0 { 242 s += "-trusted" 243 } 244 if f&dynDialedConn != 0 { 245 s += "-dyndial" 246 } 247 if f&staticDialedConn != 0 { 248 s += "-staticdial" 249 } 250 if f&inboundConn != 0 { 251 s += "-inbound" 252 } 253 if s != "" { 254 s = s[1:] 255 } 256 return s 257 } 258 259 func (c *conn) is(f connFlag) bool { 260 flags := connFlag(atomic.LoadInt32((*int32)(&c.flags))) 261 return flags&f != 0 262 } 263 264 func (c *conn) set(f connFlag, val bool) { 265 for { 266 oldFlags := connFlag(atomic.LoadInt32((*int32)(&c.flags))) 267 flags := oldFlags 268 if val { 269 flags |= f 270 } else { 271 flags &= ^f 272 } 273 if atomic.CompareAndSwapInt32((*int32)(&c.flags), int32(oldFlags), int32(flags)) { 274 return 275 } 276 } 277 } 278 279 //对等端返回所有连接的对等端。 280 func (srv *Server) Peers() []*Peer { 281 var ps []*Peer 282 select { 283 //注意:我们希望将此函数放入变量中,但是 284 //这似乎导致了一些 285 //环境。 286 case srv.peerOp <- func(peers map[enode.ID]*Peer) { 287 for _, p := range peers { 288 ps = append(ps, p) 289 } 290 }: 291 <-srv.peerOpDone 292 case <-srv.quit: 293 } 294 return ps 295 } 296 297 //PeerCount返回连接的对等数。 298 func (srv *Server) PeerCount() int { 299 var count int 300 select { 301 case srv.peerOp <- func(ps map[enode.ID]*Peer) { count = len(ps) }: 302 <-srv.peerOpDone 303 case <-srv.quit: 304 } 305 return count 306 } 307 308 //addpeer连接到给定的节点并保持连接,直到 309 //服务器已关闭。如果由于任何原因连接失败,服务器将 310 //尝试重新连接对等机。 311 func (srv *Server) AddPeer(node *enode.Node) { 312 select { 313 case srv.addstatic <- node: 314 case <-srv.quit: 315 } 316 } 317 318 //从给定节点删除对等机断开连接 319 func (srv *Server) RemovePeer(node *enode.Node) { 320 select { 321 case srv.removestatic <- node: 322 case <-srv.quit: 323 } 324 } 325 326 //addTrustedPeer将给定节点添加到保留的白名单中,该白名单允许 327 //要始终连接的节点,即使插槽已满。 328 func (srv *Server) AddTrustedPeer(node *enode.Node) { 329 select { 330 case srv.addtrusted <- node: 331 case <-srv.quit: 332 } 333 } 334 335 //removeTrustedPeer从受信任的对等集删除给定节点。 336 func (srv *Server) RemoveTrustedPeer(node *enode.Node) { 337 select { 338 case srv.removetrusted <- node: 339 case <-srv.quit: 340 } 341 } 342 343 //subscribePeers订阅给定的通道到对等事件 344 func (srv *Server) SubscribeEvents(ch chan *PeerEvent) event.Subscription { 345 return srv.peerFeed.Subscribe(ch) 346 } 347 348 //self返回本地节点的端点信息。 349 func (srv *Server) Self() *enode.Node { 350 srv.lock.Lock() 351 ln := srv.localnode 352 srv.lock.Unlock() 353 354 if ln == nil { 355 return enode.NewV4(&srv.PrivateKey.PublicKey, net.ParseIP("0.0.0.0"), 0, 0) 356 } 357 return ln.Node() 358 } 359 360 //stop终止服务器和所有活动的对等连接。 361 //它会一直阻塞,直到关闭所有活动连接。 362 func (srv *Server) Stop() { 363 srv.lock.Lock() 364 if !srv.running { 365 srv.lock.Unlock() 366 return 367 } 368 srv.running = false 369 if srv.listener != nil { 370 //此取消阻止侦听器接受 371 srv.listener.Close() 372 } 373 close(srv.quit) 374 srv.lock.Unlock() 375 srv.loopWG.Wait() 376 } 377 378 //sharedudpconn实现共享连接。写将消息发送到基础连接,而读将返回 379 //发现无法处理的消息,并由主侦听器发送到未处理的通道。 380 type sharedUDPConn struct { 381 *net.UDPConn 382 unhandled chan discover.ReadPacket 383 } 384 385 //readfromudp实现discv5.conn 386 func (s *sharedUDPConn) ReadFromUDP(b []byte) (n int, addr *net.UDPAddr, err error) { 387 packet, ok := <-s.unhandled 388 if !ok { 389 return 0, nil, errors.New("Connection was closed") 390 } 391 l := len(packet.Data) 392 if l > len(b) { 393 l = len(b) 394 } 395 copy(b[:l], packet.Data[:l]) 396 return l, packet.Addr, nil 397 } 398 399 //关闭机具discv5.conn 400 func (s *sharedUDPConn) Close() error { 401 return nil 402 } 403 404 //开始运行服务器。 405 //服务器停止后不能重新使用。 406 func (srv *Server) Start() (err error) { 407 srv.lock.Lock() 408 defer srv.lock.Unlock() 409 if srv.running { 410 return errors.New("server already running") 411 } 412 srv.running = true 413 srv.log = srv.Config.Logger 414 if srv.log == nil { 415 srv.log = log.New() 416 } 417 if srv.NoDial && srv.ListenAddr == "" { 418 srv.log.Warn("P2P server will be useless, neither dialing nor listening") 419 } 420 421 //静态场 422 if srv.PrivateKey == nil { 423 return errors.New("Server.PrivateKey must be set to a non-nil key") 424 } 425 if srv.newTransport == nil { 426 srv.newTransport = newRLPX 427 } 428 if srv.Dialer == nil { 429 srv.Dialer = TCPDialer{&net.Dialer{Timeout: defaultDialTimeout}} 430 } 431 srv.quit = make(chan struct{}) 432 srv.addpeer = make(chan *conn) 433 srv.delpeer = make(chan peerDrop) 434 srv.posthandshake = make(chan *conn) 435 srv.addstatic = make(chan *enode.Node) 436 srv.removestatic = make(chan *enode.Node) 437 srv.addtrusted = make(chan *enode.Node) 438 srv.removetrusted = make(chan *enode.Node) 439 srv.peerOp = make(chan peerOpFunc) 440 srv.peerOpDone = make(chan struct{}) 441 442 if err := srv.setupLocalNode(); err != nil { 443 return err 444 } 445 if srv.ListenAddr != "" { 446 if err := srv.setupListening(); err != nil { 447 return err 448 } 449 } 450 if err := srv.setupDiscovery(); err != nil { 451 return err 452 } 453 454 dynPeers := srv.maxDialedConns() 455 dialer := newDialState(srv.localnode.ID(), srv.StaticNodes, srv.BootstrapNodes, srv.ntab, dynPeers, srv.NetRestrict) 456 srv.loopWG.Add(1) 457 go srv.run(dialer) 458 return nil 459 } 460 461 func (srv *Server) setupLocalNode() error { 462 //创建devp2p握手。 463 pubkey := crypto.FromECDSAPub(&srv.PrivateKey.PublicKey) 464 srv.ourHandshake = &protoHandshake{Version: baseProtocolVersion, Name: srv.Name, ID: pubkey[1:]} 465 for _, p := range srv.Protocols { 466 srv.ourHandshake.Caps = append(srv.ourHandshake.Caps, p.cap()) 467 } 468 sort.Sort(capsByNameAndVersion(srv.ourHandshake.Caps)) 469 470 //创建本地节点。 471 db, err := enode.OpenDB(srv.Config.NodeDatabase) 472 if err != nil { 473 return err 474 } 475 srv.nodedb = db 476 srv.localnode = enode.NewLocalNode(db, srv.PrivateKey) 477 srv.localnode.SetFallbackIP(net.IP{127, 0, 0, 1}) 478 srv.localnode.Set(capsByNameAndVersion(srv.ourHandshake.Caps)) 479 //TODO:检查冲突 480 for _, p := range srv.Protocols { 481 for _, e := range p.Attributes { 482 srv.localnode.Set(e) 483 } 484 } 485 switch srv.NAT.(type) { 486 case nil: 487 //没有NAT接口,什么都不做。 488 case nat.ExtIP: 489 //extip不阻塞,立即设置ip。 490 ip, _ := srv.NAT.ExternalIP() 491 srv.localnode.SetStaticIP(ip) 492 default: 493 //询问路由器有关IP的信息。这需要一段时间来阻止启动, 494 //在后台进行。 495 srv.loopWG.Add(1) 496 go func() { 497 defer srv.loopWG.Done() 498 if ip, err := srv.NAT.ExternalIP(); err == nil { 499 srv.localnode.SetStaticIP(ip) 500 } 501 }() 502 } 503 return nil 504 } 505 506 func (srv *Server) setupDiscovery() error { 507 if srv.NoDiscovery && !srv.DiscoveryV5 { 508 return nil 509 } 510 511 addr, err := net.ResolveUDPAddr("udp", srv.ListenAddr) 512 if err != nil { 513 return err 514 } 515 conn, err := net.ListenUDP("udp", addr) 516 if err != nil { 517 return err 518 } 519 realaddr := conn.LocalAddr().(*net.UDPAddr) 520 srv.log.Debug("UDP listener up", "addr", realaddr) 521 if srv.NAT != nil { 522 if !realaddr.IP.IsLoopback() { 523 go nat.Map(srv.NAT, srv.quit, "udp", realaddr.Port, realaddr.Port, "ethereum discovery") 524 } 525 } 526 srv.localnode.SetFallbackUDP(realaddr.Port) 527 528 //发现V4 529 var unhandled chan discover.ReadPacket 530 var sconn *sharedUDPConn 531 if !srv.NoDiscovery { 532 if srv.DiscoveryV5 { 533 unhandled = make(chan discover.ReadPacket, 100) 534 sconn = &sharedUDPConn{conn, unhandled} 535 } 536 cfg := discover.Config{ 537 PrivateKey: srv.PrivateKey, 538 NetRestrict: srv.NetRestrict, 539 Bootnodes: srv.BootstrapNodes, 540 Unhandled: unhandled, 541 } 542 ntab, err := discover.ListenUDP(conn, srv.localnode, cfg) 543 if err != nil { 544 return err 545 } 546 srv.ntab = ntab 547 } 548 //发现V5 549 if srv.DiscoveryV5 { 550 var ntab *discv5.Network 551 var err error 552 if sconn != nil { 553 ntab, err = discv5.ListenUDP(srv.PrivateKey, sconn, "", srv.NetRestrict) 554 } else { 555 ntab, err = discv5.ListenUDP(srv.PrivateKey, conn, "", srv.NetRestrict) 556 } 557 if err != nil { 558 return err 559 } 560 if err := ntab.SetFallbackNodes(srv.BootstrapNodesV5); err != nil { 561 return err 562 } 563 srv.DiscV5 = ntab 564 } 565 return nil 566 } 567 568 func (srv *Server) setupListening() error { 569 //启动TCP侦听器。 570 listener, err := net.Listen("tcp", srv.ListenAddr) 571 if err != nil { 572 return err 573 } 574 laddr := listener.Addr().(*net.TCPAddr) 575 srv.ListenAddr = laddr.String() 576 srv.listener = listener 577 srv.localnode.Set(enr.TCP(laddr.Port)) 578 579 srv.loopWG.Add(1) 580 go srv.listenLoop() 581 582 //如果配置了NAT,则映射TCP侦听端口。 583 if !laddr.IP.IsLoopback() && srv.NAT != nil { 584 srv.loopWG.Add(1) 585 go func() { 586 nat.Map(srv.NAT, srv.quit, "tcp", laddr.Port, laddr.Port, "ethereum p2p") 587 srv.loopWG.Done() 588 }() 589 } 590 return nil 591 } 592 593 type dialer interface { 594 newTasks(running int, peers map[enode.ID]*Peer, now time.Time) []task 595 taskDone(task, time.Time) 596 addStatic(*enode.Node) 597 removeStatic(*enode.Node) 598 } 599 600 func (srv *Server) run(dialstate dialer) { 601 srv.log.Info("Started P2P networking", "self", srv.localnode.Node()) 602 defer srv.loopWG.Done() 603 defer srv.nodedb.Close() 604 605 var ( 606 peers = make(map[enode.ID]*Peer) 607 inboundCount = 0 608 trusted = make(map[enode.ID]bool, len(srv.TrustedNodes)) 609 taskdone = make(chan task, maxActiveDialTasks) 610 runningTasks []task 611 queuedTasks []task //尚未运行的任务 612 ) 613 //将受信任的节点放入映射以加快检查速度。 614 //可信对等机在启动时加载或通过addtrustedpeer rpc添加。 615 for _, n := range srv.TrustedNodes { 616 trusted[n.ID()] = true 617 } 618 619 //从运行任务中删除t 620 delTask := func(t task) { 621 for i := range runningTasks { 622 if runningTasks[i] == t { 623 runningTasks = append(runningTasks[:i], runningTasks[i+1:]...) 624 break 625 } 626 } 627 } 628 //在满足最大活动任务数之前启动 629 startTasks := func(ts []task) (rest []task) { 630 i := 0 631 for ; len(runningTasks) < maxActiveDialTasks && i < len(ts); i++ { 632 t := ts[i] 633 srv.log.Trace("New dial task", "task", t) 634 go func() { t.Do(srv); taskdone <- t }() 635 runningTasks = append(runningTasks, t) 636 } 637 return ts[i:] 638 } 639 scheduleTasks := func() { 640 //先从队列开始。 641 queuedTasks = append(queuedTasks[:0], startTasks(queuedTasks)...) 642 //查询拨号程序以查找新任务,并立即尽可能多地启动。 643 if len(runningTasks) < maxActiveDialTasks { 644 nt := dialstate.newTasks(len(runningTasks)+len(queuedTasks), peers, time.Now()) 645 queuedTasks = append(queuedTasks, startTasks(nt)...) 646 } 647 } 648 649 running: 650 for { 651 scheduleTasks() 652 653 select { 654 case <-srv.quit: 655 //服务器已停止。运行清除逻辑。 656 break running 657 case n := <-srv.addstatic: 658 //addpeer使用此通道添加到 659 //短暂的静态对等列表。把它加到拨号器上, 660 //它将保持节点连接。 661 srv.log.Trace("Adding static node", "node", n) 662 dialstate.addStatic(n) 663 case n := <-srv.removestatic: 664 //removepeer使用此通道发送 665 //断开对对等机的请求并开始 666 //停止保持节点连接。 667 srv.log.Trace("Removing static node", "node", n) 668 dialstate.removeStatic(n) 669 if p, ok := peers[n.ID()]; ok { 670 p.Disconnect(DiscRequested) 671 } 672 case n := <-srv.addtrusted: 673 //addTrustedPeer使用此通道添加enode 674 //到受信任的节点集。 675 srv.log.Trace("Adding trusted node", "node", n) 676 trusted[n.ID()] = true 677 //将任何已连接的对等机标记为受信任 678 if p, ok := peers[n.ID()]; ok { 679 p.rw.set(trustedConn, true) 680 } 681 case n := <-srv.removetrusted: 682 //此通道由removeTrustedPeer用于删除enode 683 //来自受信任的节点集。 684 srv.log.Trace("Removing trusted node", "node", n) 685 if _, ok := trusted[n.ID()]; ok { 686 delete(trusted, n.ID()) 687 } 688 //将任何已连接的对等机取消标记为受信任 689 if p, ok := peers[n.ID()]; ok { 690 p.rw.set(trustedConn, false) 691 } 692 case op := <-srv.peerOp: 693 //此通道由对等方和对等方使用。 694 op(peers) 695 srv.peerOpDone <- struct{}{} 696 case t := <-taskdone: 697 //任务完成了。告诉Dialstate,所以 698 //可以更新其状态并将其从活动 699 //任务列表。 700 srv.log.Trace("Dial task done", "task", t) 701 dialstate.taskDone(t, time.Now()) 702 delTask(t) 703 case c := <-srv.posthandshake: 704 //连接已通过加密握手,因此 705 //远程标识已知(但尚未验证)。 706 if trusted[c.node.ID()] { 707 //在对MaxPeers进行检查之前,请确保设置了可信标志。 708 c.flags |= trustedConn 709 } 710 //TODO:跟踪正在进行的入站节点ID(预对等),以避免拨号。 711 select { 712 case c.cont <- srv.encHandshakeChecks(peers, inboundCount, c): 713 case <-srv.quit: 714 break running 715 } 716 case c := <-srv.addpeer: 717 //此时,连接已超过协议握手。 718 //它的功能是已知的,并且远程身份被验证。 719 err := srv.protoHandshakeChecks(peers, inboundCount, c) 720 if err == nil { 721 //握手完成,通过所有检查。 722 p := newPeer(c, srv.Protocols) 723 //如果启用了消息事件,则传递peerfeed 724 //向同行 725 if srv.EnableMsgEvents { 726 p.events = &srv.peerFeed 727 } 728 name := truncateName(c.name) 729 srv.log.Debug("Adding p2p peer", "name", name, "addr", c.fd.RemoteAddr(), "peers", len(peers)+1) 730 go srv.runPeer(p) 731 peers[c.node.ID()] = p 732 if p.Inbound() { 733 inboundCount++ 734 } 735 } 736 //拨号程序逻辑依赖于以下假设: 737 //添加对等机后完成拨号任务,或者 738 //丢弃的。最后取消阻止任务。 739 select { 740 case c.cont <- err: 741 case <-srv.quit: 742 break running 743 } 744 case pd := <-srv.delpeer: 745 //已断开连接的对等机。 746 d := common.PrettyDuration(mclock.Now() - pd.created) 747 pd.log.Debug("Removing p2p peer", "duration", d, "peers", len(peers)-1, "req", pd.requested, "err", pd.err) 748 delete(peers, pd.ID()) 749 if pd.Inbound() { 750 inboundCount-- 751 } 752 } 753 } 754 755 srv.log.Trace("P2P networking is spinning down") 756 757 //终止发现。如果有正在运行的查找,它将很快终止。 758 if srv.ntab != nil { 759 srv.ntab.Close() 760 } 761 if srv.DiscV5 != nil { 762 srv.DiscV5.Close() 763 } 764 //断开所有对等机的连接。 765 for _, p := range peers { 766 p.Disconnect(DiscQuitting) 767 } 768 //等待对等机关闭。挂起的连接和任务是 769 //此处未处理,将很快终止,因为srv.quit 770 //关闭。 771 for len(peers) > 0 { 772 p := <-srv.delpeer 773 p.log.Trace("<-delpeer (spindown)", "remainingTasks", len(runningTasks)) 774 delete(peers, p.ID()) 775 } 776 } 777 778 func (srv *Server) protoHandshakeChecks(peers map[enode.ID]*Peer, inboundCount int, c *conn) error { 779 //删除没有匹配协议的连接。 780 if len(srv.Protocols) > 0 && countMatchingProtocols(srv.Protocols, c.caps) == 0 { 781 return DiscUselessPeer 782 } 783 //重复加密握手检查,因为 784 //对等机集可能在握手之间发生了更改。 785 return srv.encHandshakeChecks(peers, inboundCount, c) 786 } 787 788 func (srv *Server) encHandshakeChecks(peers map[enode.ID]*Peer, inboundCount int, c *conn) error { 789 switch { 790 case !c.is(trustedConn|staticDialedConn) && len(peers) >= srv.MaxPeers: 791 return DiscTooManyPeers 792 case !c.is(trustedConn) && c.is(inboundConn) && inboundCount >= srv.maxInboundConns(): 793 return DiscTooManyPeers 794 case peers[c.node.ID()] != nil: 795 return DiscAlreadyConnected 796 case c.node.ID() == srv.localnode.ID(): 797 return DiscSelf 798 default: 799 return nil 800 } 801 } 802 803 func (srv *Server) maxInboundConns() int { 804 return srv.MaxPeers - srv.maxDialedConns() 805 } 806 func (srv *Server) maxDialedConns() int { 807 if srv.NoDiscovery || srv.NoDial { 808 return 0 809 } 810 r := srv.DialRatio 811 if r == 0 { 812 r = defaultDialRatio 813 } 814 return srv.MaxPeers / r 815 } 816 817 //listenloop在自己的goroutine中运行并接受 818 //入站连接。 819 func (srv *Server) listenLoop() { 820 defer srv.loopWG.Done() 821 srv.log.Debug("TCP listener up", "addr", srv.listener.Addr()) 822 823 tokens := defaultMaxPendingPeers 824 if srv.MaxPendingPeers > 0 { 825 tokens = srv.MaxPendingPeers 826 } 827 slots := make(chan struct{}, tokens) 828 for i := 0; i < tokens; i++ { 829 slots <- struct{}{} 830 } 831 832 for { 833 //在接受前等待握手槽。 834 <-slots 835 836 var ( 837 fd net.Conn 838 err error 839 ) 840 for { 841 fd, err = srv.listener.Accept() 842 if netutil.IsTemporaryError(err) { 843 srv.log.Debug("Temporary read error", "err", err) 844 continue 845 } else if err != nil { 846 srv.log.Debug("Read error", "err", err) 847 return 848 } 849 break 850 } 851 852 //拒绝与NetRestrict不匹配的连接。 853 if srv.NetRestrict != nil { 854 if tcp, ok := fd.RemoteAddr().(*net.TCPAddr); ok && !srv.NetRestrict.Contains(tcp.IP) { 855 srv.log.Debug("Rejected conn (not whitelisted in NetRestrict)", "addr", fd.RemoteAddr()) 856 fd.Close() 857 slots <- struct{}{} 858 continue 859 } 860 } 861 862 var ip net.IP 863 if tcp, ok := fd.RemoteAddr().(*net.TCPAddr); ok { 864 ip = tcp.IP 865 } 866 fd = newMeteredConn(fd, true, ip) 867 srv.log.Trace("Accepted connection", "addr", fd.RemoteAddr()) 868 go func() { 869 srv.SetupConn(fd, inboundConn, nil) 870 slots <- struct{}{} 871 }() 872 } 873 } 874 875 //SetupConn运行握手并尝试添加连接 876 //作为同伴。当连接添加为对等时返回 877 //或者握手失败。 878 func (srv *Server) SetupConn(fd net.Conn, flags connFlag, dialDest *enode.Node) error { 879 c := &conn{fd: fd, transport: srv.newTransport(fd), flags: flags, cont: make(chan error)} 880 err := srv.setupConn(c, flags, dialDest) 881 if err != nil { 882 c.close(err) 883 srv.log.Trace("Setting up connection failed", "addr", fd.RemoteAddr(), "err", err) 884 } 885 return err 886 } 887 888 func (srv *Server) setupConn(c *conn, flags connFlag, dialDest *enode.Node) error { 889 //防止剩余的挂起conn进入握手。 890 srv.lock.Lock() 891 running := srv.running 892 srv.lock.Unlock() 893 if !running { 894 return errServerStopped 895 } 896 //如果拨号,请找出远程公钥。 897 var dialPubkey *ecdsa.PublicKey 898 if dialDest != nil { 899 dialPubkey = new(ecdsa.PublicKey) 900 if err := dialDest.Load((*enode.Secp256k1)(dialPubkey)); err != nil { 901 return errors.New("dial destination doesn't have a secp256k1 public key") 902 } 903 } 904 //运行加密握手。 905 remotePubkey, err := c.doEncHandshake(srv.PrivateKey, dialPubkey) 906 if err != nil { 907 srv.log.Trace("Failed RLPx handshake", "addr", c.fd.RemoteAddr(), "conn", c.flags, "err", err) 908 return err 909 } 910 if dialDest != nil { 911 //对于拨号连接,请检查远程公钥是否匹配。 912 if dialPubkey.X.Cmp(remotePubkey.X) != 0 || dialPubkey.Y.Cmp(remotePubkey.Y) != 0 { 913 return DiscUnexpectedIdentity 914 } 915 c.node = dialDest 916 } else { 917 c.node = nodeFromConn(remotePubkey, c.fd) 918 } 919 if conn, ok := c.fd.(*meteredConn); ok { 920 conn.handshakeDone(c.node.ID()) 921 } 922 clog := srv.log.New("id", c.node.ID(), "addr", c.fd.RemoteAddr(), "conn", c.flags) 923 err = srv.checkpoint(c, srv.posthandshake) 924 if err != nil { 925 clog.Trace("Rejected peer before protocol handshake", "err", err) 926 return err 927 } 928 //运行协议握手 929 phs, err := c.doProtoHandshake(srv.ourHandshake) 930 if err != nil { 931 clog.Trace("Failed proto handshake", "err", err) 932 return err 933 } 934 if id := c.node.ID(); !bytes.Equal(crypto.Keccak256(phs.ID), id[:]) { 935 clog.Trace("Wrong devp2p handshake identity", "phsid", hex.EncodeToString(phs.ID)) 936 return DiscUnexpectedIdentity 937 } 938 c.caps, c.name = phs.Caps, phs.Name 939 err = srv.checkpoint(c, srv.addpeer) 940 if err != nil { 941 clog.Trace("Rejected peer", "err", err) 942 return err 943 } 944 //如果检查成功完成,runpeer现在已经 945 //由run启动。 946 clog.Trace("connection set up", "inbound", dialDest == nil) 947 return nil 948 } 949 950 func nodeFromConn(pubkey *ecdsa.PublicKey, conn net.Conn) *enode.Node { 951 var ip net.IP 952 var port int 953 if tcp, ok := conn.RemoteAddr().(*net.TCPAddr); ok { 954 ip = tcp.IP 955 port = tcp.Port 956 } 957 return enode.NewV4(pubkey, ip, port, port) 958 } 959 960 func truncateName(s string) string { 961 if len(s) > 20 { 962 return s[:20] + "..." 963 } 964 return s 965 } 966 967 //检查点发送conn运行,它执行 968 //阶段的后握手检查(后握手,addpeer)。 969 func (srv *Server) checkpoint(c *conn, stage chan<- *conn) error { 970 select { 971 case stage <- c: 972 case <-srv.quit: 973 return errServerStopped 974 } 975 select { 976 case err := <-c.cont: 977 return err 978 case <-srv.quit: 979 return errServerStopped 980 } 981 } 982 983 //runpeer为每个对等运行自己的goroutine。 984 //它等待直到对等逻辑返回并删除 985 //同辈。 986 func (srv *Server) runPeer(p *Peer) { 987 if srv.newPeerHook != nil { 988 srv.newPeerHook(p) 989 } 990 991 //广播对等添加 992 srv.peerFeed.Send(&PeerEvent{ 993 Type: PeerEventTypeAdd, 994 Peer: p.ID(), 995 }) 996 997 //运行协议 998 remoteRequested, err := p.run() 999 1000 //广播对等丢弃 1001 srv.peerFeed.Send(&PeerEvent{ 1002 Type: PeerEventTypeDrop, 1003 Peer: p.ID(), 1004 Error: err.Error(), 1005 }) 1006 1007 //注意:run等待现有对等机在srv.delpeer上发送 1008 //返回之前,不应在srv.quit上选择此发送。 1009 srv.delpeer <- peerDrop{p, err, remoteRequested} 1010 } 1011 1012 //nodeinfo表示有关主机的已知信息的简短摘要。 1013 type NodeInfo struct { 1014 ID string `json:"id"` //唯一节点标识符(也是加密密钥) 1015 Name string `json:"name"` //节点的名称,包括客户端类型、版本、操作系统、自定义数据 1016 Enode string `json:"enode"` //用于从远程对等添加此对等的enode url 1017 ENR string `json:"enr"` //以太坊节点记录 1018 IP string `json:"ip"` //节点的IP地址 1019 Ports struct { 1020 Discovery int `json:"discovery"` //发现协议的UDP侦听端口 1021 Listener int `json:"listener"` //rlpx的TCP侦听端口 1022 } `json:"ports"` 1023 ListenAddr string `json:"listenAddr"` 1024 Protocols map[string]interface{} `json:"protocols"` 1025 } 1026 1027 //nodeinfo收集并返回有关主机的已知元数据集合。 1028 func (srv *Server) NodeInfo() *NodeInfo { 1029 //收集和组装通用节点信息 1030 node := srv.Self() 1031 info := &NodeInfo{ 1032 Name: srv.Name, 1033 Enode: node.String(), 1034 ID: node.ID().String(), 1035 IP: node.IP().String(), 1036 ListenAddr: srv.ListenAddr, 1037 Protocols: make(map[string]interface{}), 1038 } 1039 info.Ports.Discovery = node.UDP() 1040 info.Ports.Listener = node.TCP() 1041 if enc, err := rlp.EncodeToBytes(node.Record()); err == nil { 1042 info.ENR = "0x" + hex.EncodeToString(enc) 1043 } 1044 1045 //收集所有正在运行的协议信息(每个协议类型仅一次) 1046 for _, proto := range srv.Protocols { 1047 if _, ok := info.Protocols[proto.Name]; !ok { 1048 nodeInfo := interface{}("unknown") 1049 if query := proto.NodeInfo; query != nil { 1050 nodeInfo = proto.NodeInfo() 1051 } 1052 info.Protocols[proto.Name] = nodeInfo 1053 } 1054 } 1055 return info 1056 } 1057 1058 //PeerSinfo返回描述已连接对等端的元数据对象数组。 1059 func (srv *Server) PeersInfo() []*PeerInfo { 1060 //收集所有通用和子协议特定的信息 1061 infos := make([]*PeerInfo, 0, srv.PeerCount()) 1062 for _, peer := range srv.Peers() { 1063 if peer != nil { 1064 infos = append(infos, peer.Info()) 1065 } 1066 } 1067 //按节点标识符的字母顺序对结果数组排序 1068 for i := 0; i < len(infos); i++ { 1069 for j := i + 1; j < len(infos); j++ { 1070 if infos[i].ID > infos[j].ID { 1071 infos[i], infos[j] = infos[j], infos[i] 1072 } 1073 } 1074 } 1075 return infos 1076 } 1077