github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/p2p/simulations/network.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:42</date> 10 //</624450107105873920> 11 12 13 package simulations 14 15 import ( 16 "bytes" 17 "context" 18 "encoding/json" 19 "errors" 20 "fmt" 21 "math/rand" 22 "sync" 23 "time" 24 25 "github.com/ethereum/go-ethereum/event" 26 "github.com/ethereum/go-ethereum/log" 27 "github.com/ethereum/go-ethereum/p2p" 28 "github.com/ethereum/go-ethereum/p2p/enode" 29 "github.com/ethereum/go-ethereum/p2p/simulations/adapters" 30 ) 31 32 var DialBanTimeout = 200 * time.Millisecond 33 34 //networkconfig定义用于启动网络的配置选项 35 type NetworkConfig struct { 36 ID string `json:"id"` 37 DefaultService string `json:"default_service,omitempty"` 38 } 39 40 //网络模型一个P2P仿真网络,它由一组 41 //模拟节点及其之间存在的连接。 42 // 43 //网络有一个单独的节点适配器,它实际上负责 44 //启动节点并将它们连接在一起。 45 // 46 //当节点启动和停止时,网络会发出事件 47 //连接和断开连接,以及在节点之间发送消息时。 48 type Network struct { 49 NetworkConfig 50 51 Nodes []*Node `json:"nodes"` 52 nodeMap map[enode.ID]int 53 54 Conns []*Conn `json:"conns"` 55 connMap map[string]int 56 57 nodeAdapter adapters.NodeAdapter 58 events event.Feed 59 lock sync.RWMutex 60 quitc chan struct{} 61 } 62 63 //newnetwork返回使用给定nodeadapter和networkconfig的网络 64 func NewNetwork(nodeAdapter adapters.NodeAdapter, conf *NetworkConfig) *Network { 65 return &Network{ 66 NetworkConfig: *conf, 67 nodeAdapter: nodeAdapter, 68 nodeMap: make(map[enode.ID]int), 69 connMap: make(map[string]int), 70 quitc: make(chan struct{}), 71 } 72 } 73 74 //事件返回网络的输出事件源。 75 func (net *Network) Events() *event.Feed { 76 return &net.events 77 } 78 79 //new node with config使用给定的配置向网络添加新节点, 80 //如果已存在具有相同ID或名称的节点,则返回错误 81 func (net *Network) NewNodeWithConfig(conf *adapters.NodeConfig) (*Node, error) { 82 net.lock.Lock() 83 defer net.lock.Unlock() 84 85 if conf.Reachable == nil { 86 conf.Reachable = func(otherID enode.ID) bool { 87 _, err := net.InitConn(conf.ID, otherID) 88 if err != nil && bytes.Compare(conf.ID.Bytes(), otherID.Bytes()) < 0 { 89 return false 90 } 91 return true 92 } 93 } 94 95 //检查节点是否已存在 96 if node := net.getNode(conf.ID); node != nil { 97 return nil, fmt.Errorf("node with ID %q already exists", conf.ID) 98 } 99 if node := net.getNodeByName(conf.Name); node != nil { 100 return nil, fmt.Errorf("node with name %q already exists", conf.Name) 101 } 102 103 //如果未配置任何服务,请使用默认服务 104 if len(conf.Services) == 0 { 105 conf.Services = []string{net.DefaultService} 106 } 107 108 //使用nodeadapter创建节点 109 adapterNode, err := net.nodeAdapter.NewNode(conf) 110 if err != nil { 111 return nil, err 112 } 113 node := &Node{ 114 Node: adapterNode, 115 Config: conf, 116 } 117 log.Trace("Node created", "id", conf.ID) 118 net.nodeMap[conf.ID] = len(net.Nodes) 119 net.Nodes = append(net.Nodes, node) 120 121 //发出“控制”事件 122 net.events.Send(ControlEvent(node)) 123 124 return node, nil 125 } 126 127 //config返回网络配置 128 func (net *Network) Config() *NetworkConfig { 129 return &net.NetworkConfig 130 } 131 132 //StartAll启动网络中的所有节点 133 func (net *Network) StartAll() error { 134 for _, node := range net.Nodes { 135 if node.Up { 136 continue 137 } 138 if err := net.Start(node.ID()); err != nil { 139 return err 140 } 141 } 142 return nil 143 } 144 145 //stopall停止网络中的所有节点 146 func (net *Network) StopAll() error { 147 for _, node := range net.Nodes { 148 if !node.Up { 149 continue 150 } 151 if err := net.Stop(node.ID()); err != nil { 152 return err 153 } 154 } 155 return nil 156 } 157 158 //Start用给定的ID启动节点 159 func (net *Network) Start(id enode.ID) error { 160 return net.startWithSnapshots(id, nil) 161 } 162 163 //StartWithSnapshots使用给定的ID启动节点 164 //快照 165 func (net *Network) startWithSnapshots(id enode.ID, snapshots map[string][]byte) error { 166 net.lock.Lock() 167 defer net.lock.Unlock() 168 169 node := net.getNode(id) 170 if node == nil { 171 return fmt.Errorf("node %v does not exist", id) 172 } 173 if node.Up { 174 return fmt.Errorf("node %v already up", id) 175 } 176 log.Trace("Starting node", "id", id, "adapter", net.nodeAdapter.Name()) 177 if err := node.Start(snapshots); err != nil { 178 log.Warn("Node startup failed", "id", id, "err", err) 179 return err 180 } 181 node.Up = true 182 log.Info("Started node", "id", id) 183 184 net.events.Send(NewEvent(node)) 185 186 //订阅对等事件 187 client, err := node.Client() 188 if err != nil { 189 return fmt.Errorf("error getting rpc client for node %v: %s", id, err) 190 } 191 events := make(chan *p2p.PeerEvent) 192 sub, err := client.Subscribe(context.Background(), "admin", events, "peerEvents") 193 if err != nil { 194 return fmt.Errorf("error getting peer events for node %v: %s", id, err) 195 } 196 go net.watchPeerEvents(id, events, sub) 197 return nil 198 } 199 200 //WatchPeerEvents从给定通道读取对等事件并发出 201 //相应的网络事件 202 func (net *Network) watchPeerEvents(id enode.ID, events chan *p2p.PeerEvent, sub event.Subscription) { 203 defer func() { 204 sub.Unsubscribe() 205 206 //假设节点现在已关闭 207 net.lock.Lock() 208 defer net.lock.Unlock() 209 node := net.getNode(id) 210 if node == nil { 211 return 212 } 213 node.Up = false 214 net.events.Send(NewEvent(node)) 215 }() 216 for { 217 select { 218 case event, ok := <-events: 219 if !ok { 220 return 221 } 222 peer := event.Peer 223 switch event.Type { 224 225 case p2p.PeerEventTypeAdd: 226 net.DidConnect(id, peer) 227 228 case p2p.PeerEventTypeDrop: 229 net.DidDisconnect(id, peer) 230 231 case p2p.PeerEventTypeMsgSend: 232 net.DidSend(id, peer, event.Protocol, *event.MsgCode) 233 234 case p2p.PeerEventTypeMsgRecv: 235 net.DidReceive(peer, id, event.Protocol, *event.MsgCode) 236 237 } 238 239 case err := <-sub.Err(): 240 if err != nil { 241 log.Error("Error in peer event subscription", "id", id, "err", err) 242 } 243 return 244 } 245 } 246 } 247 248 //stop停止具有给定ID的节点 249 func (net *Network) Stop(id enode.ID) error { 250 net.lock.Lock() 251 node := net.getNode(id) 252 if node == nil { 253 return fmt.Errorf("node %v does not exist", id) 254 } 255 if !node.Up { 256 return fmt.Errorf("node %v already down", id) 257 } 258 node.Up = false 259 net.lock.Unlock() 260 261 err := node.Stop() 262 if err != nil { 263 net.lock.Lock() 264 node.Up = true 265 net.lock.Unlock() 266 return err 267 } 268 log.Info("Stopped node", "id", id, "err", err) 269 net.events.Send(ControlEvent(node)) 270 return nil 271 } 272 273 //connect通过调用“admin_addpeer”rpc将两个节点连接在一起 274 //方法,以便它连接到“另一个”节点 275 func (net *Network) Connect(oneID, otherID enode.ID) error { 276 log.Debug("Connecting nodes with addPeer", "id", oneID, "other", otherID) 277 conn, err := net.InitConn(oneID, otherID) 278 if err != nil { 279 return err 280 } 281 client, err := conn.one.Client() 282 if err != nil { 283 return err 284 } 285 net.events.Send(ControlEvent(conn)) 286 return client.Call(nil, "admin_addPeer", string(conn.other.Addr())) 287 } 288 289 //断开连接通过调用“admin-removepeer”rpc断开两个节点的连接 290 //方法,以便它与“另一个”节点断开连接 291 func (net *Network) Disconnect(oneID, otherID enode.ID) error { 292 conn := net.GetConn(oneID, otherID) 293 if conn == nil { 294 return fmt.Errorf("connection between %v and %v does not exist", oneID, otherID) 295 } 296 if !conn.Up { 297 return fmt.Errorf("%v and %v already disconnected", oneID, otherID) 298 } 299 client, err := conn.one.Client() 300 if err != nil { 301 return err 302 } 303 net.events.Send(ControlEvent(conn)) 304 return client.Call(nil, "admin_removePeer", string(conn.other.Addr())) 305 } 306 307 //didconnect跟踪“一个”节点连接到“另一个”节点的事实 308 func (net *Network) DidConnect(one, other enode.ID) error { 309 net.lock.Lock() 310 defer net.lock.Unlock() 311 conn, err := net.getOrCreateConn(one, other) 312 if err != nil { 313 return fmt.Errorf("connection between %v and %v does not exist", one, other) 314 } 315 if conn.Up { 316 return fmt.Errorf("%v and %v already connected", one, other) 317 } 318 conn.Up = true 319 net.events.Send(NewEvent(conn)) 320 return nil 321 } 322 323 //didisconnect跟踪“one”节点与 324 //“其他”节点 325 func (net *Network) DidDisconnect(one, other enode.ID) error { 326 net.lock.Lock() 327 defer net.lock.Unlock() 328 conn := net.getConn(one, other) 329 if conn == nil { 330 return fmt.Errorf("connection between %v and %v does not exist", one, other) 331 } 332 if !conn.Up { 333 return fmt.Errorf("%v and %v already disconnected", one, other) 334 } 335 conn.Up = false 336 conn.initiated = time.Now().Add(-DialBanTimeout) 337 net.events.Send(NewEvent(conn)) 338 return nil 339 } 340 341 //didsend跟踪“sender”向“receiver”发送消息的事实 342 func (net *Network) DidSend(sender, receiver enode.ID, proto string, code uint64) error { 343 msg := &Msg{ 344 One: sender, 345 Other: receiver, 346 Protocol: proto, 347 Code: code, 348 Received: false, 349 } 350 net.events.Send(NewEvent(msg)) 351 return nil 352 } 353 354 //DidReceive跟踪“Receiver”从“Sender”收到消息的事实 355 func (net *Network) DidReceive(sender, receiver enode.ID, proto string, code uint64) error { 356 msg := &Msg{ 357 One: sender, 358 Other: receiver, 359 Protocol: proto, 360 Code: code, 361 Received: true, 362 } 363 net.events.Send(NewEvent(msg)) 364 return nil 365 } 366 367 //getnode获取具有给定ID的节点,如果该节点没有,则返回nil 368 //存在 369 func (net *Network) GetNode(id enode.ID) *Node { 370 net.lock.RLock() 371 defer net.lock.RUnlock() 372 return net.getNode(id) 373 } 374 375 //getnode获取具有给定名称的节点,如果该节点执行此操作,则返回nil 376 //不存在 377 func (net *Network) GetNodeByName(name string) *Node { 378 net.lock.RLock() 379 defer net.lock.RUnlock() 380 return net.getNodeByName(name) 381 } 382 383 func (net *Network) getNodeByName(name string) *Node { 384 for _, node := range net.Nodes { 385 if node.Config.Name == name { 386 return node 387 } 388 } 389 return nil 390 } 391 392 //GetNodes返回现有节点 393 func (net *Network) GetNodes() (nodes []*Node) { 394 net.lock.RLock() 395 defer net.lock.RUnlock() 396 397 nodes = append(nodes, net.Nodes...) 398 return nodes 399 } 400 401 func (net *Network) getNode(id enode.ID) *Node { 402 i, found := net.nodeMap[id] 403 if !found { 404 return nil 405 } 406 return net.Nodes[i] 407 } 408 409 //getrandomupnode返回网络上正在运行的随机节点。 410 func (net *Network) GetRandomUpNode(excludeIDs ...enode.ID) *Node { 411 net.lock.RLock() 412 defer net.lock.RUnlock() 413 return net.getRandomNode(net.getUpNodeIDs(), excludeIDs) 414 } 415 416 func (net *Network) getUpNodeIDs() (ids []enode.ID) { 417 for _, node := range net.Nodes { 418 if node.Up { 419 ids = append(ids, node.ID()) 420 } 421 } 422 return ids 423 } 424 425 //GetRandomDownNode返回网络上的随机节点,该节点已停止。 426 func (net *Network) GetRandomDownNode(excludeIDs ...enode.ID) *Node { 427 net.lock.RLock() 428 defer net.lock.RUnlock() 429 return net.getRandomNode(net.getDownNodeIDs(), excludeIDs) 430 } 431 432 func (net *Network) getDownNodeIDs() (ids []enode.ID) { 433 for _, node := range net.GetNodes() { 434 if !node.Up { 435 ids = append(ids, node.ID()) 436 } 437 } 438 return ids 439 } 440 441 func (net *Network) getRandomNode(ids []enode.ID, excludeIDs []enode.ID) *Node { 442 filtered := filterIDs(ids, excludeIDs) 443 444 l := len(filtered) 445 if l == 0 { 446 return nil 447 } 448 return net.GetNode(filtered[rand.Intn(l)]) 449 } 450 451 func filterIDs(ids []enode.ID, excludeIDs []enode.ID) []enode.ID { 452 exclude := make(map[enode.ID]bool) 453 for _, id := range excludeIDs { 454 exclude[id] = true 455 } 456 var filtered []enode.ID 457 for _, id := range ids { 458 if _, found := exclude[id]; !found { 459 filtered = append(filtered, id) 460 } 461 } 462 return filtered 463 } 464 465 //getconn返回“一”和“另一”之间存在的连接 466 //无论哪个节点启动了连接 467 func (net *Network) GetConn(oneID, otherID enode.ID) *Conn { 468 net.lock.RLock() 469 defer net.lock.RUnlock() 470 return net.getConn(oneID, otherID) 471 } 472 473 //getorCreateConn与getconn类似,但如果不相同,则创建连接 474 //已经存在 475 func (net *Network) GetOrCreateConn(oneID, otherID enode.ID) (*Conn, error) { 476 net.lock.Lock() 477 defer net.lock.Unlock() 478 return net.getOrCreateConn(oneID, otherID) 479 } 480 481 func (net *Network) getOrCreateConn(oneID, otherID enode.ID) (*Conn, error) { 482 if conn := net.getConn(oneID, otherID); conn != nil { 483 return conn, nil 484 } 485 486 one := net.getNode(oneID) 487 if one == nil { 488 return nil, fmt.Errorf("node %v does not exist", oneID) 489 } 490 other := net.getNode(otherID) 491 if other == nil { 492 return nil, fmt.Errorf("node %v does not exist", otherID) 493 } 494 conn := &Conn{ 495 One: oneID, 496 Other: otherID, 497 one: one, 498 other: other, 499 } 500 label := ConnLabel(oneID, otherID) 501 net.connMap[label] = len(net.Conns) 502 net.Conns = append(net.Conns, conn) 503 return conn, nil 504 } 505 506 func (net *Network) getConn(oneID, otherID enode.ID) *Conn { 507 label := ConnLabel(oneID, otherID) 508 i, found := net.connMap[label] 509 if !found { 510 return nil 511 } 512 return net.Conns[i] 513 } 514 515 //initconn(一个,另一个)检索 516 //彼此对等,如果不存在则创建一个新的 517 //节点顺序无关紧要,即conn(i,j)==conn(j,i) 518 //它检查连接是否已经启动,以及节点是否正在运行 519 //注: 520 //它还检查最近是否有连接对等端的尝试 521 //这是欺骗,因为模拟被用作甲骨文并知道 522 //远程对等机尝试连接到一个节点,该节点随后将不会启动连接。 523 func (net *Network) InitConn(oneID, otherID enode.ID) (*Conn, error) { 524 net.lock.Lock() 525 defer net.lock.Unlock() 526 if oneID == otherID { 527 return nil, fmt.Errorf("refusing to connect to self %v", oneID) 528 } 529 conn, err := net.getOrCreateConn(oneID, otherID) 530 if err != nil { 531 return nil, err 532 } 533 if conn.Up { 534 return nil, fmt.Errorf("%v and %v already connected", oneID, otherID) 535 } 536 if time.Since(conn.initiated) < DialBanTimeout { 537 return nil, fmt.Errorf("connection between %v and %v recently attempted", oneID, otherID) 538 } 539 540 err = conn.nodesUp() 541 if err != nil { 542 log.Trace("Nodes not up", "err", err) 543 return nil, fmt.Errorf("nodes not up: %v", err) 544 } 545 log.Debug("Connection initiated", "id", oneID, "other", otherID) 546 conn.initiated = time.Now() 547 return conn, nil 548 } 549 550 //shutdown停止网络中的所有节点并关闭退出通道 551 func (net *Network) Shutdown() { 552 for _, node := range net.Nodes { 553 log.Debug("Stopping node", "id", node.ID()) 554 if err := node.Stop(); err != nil { 555 log.Warn("Can't stop node", "id", node.ID(), "err", err) 556 } 557 } 558 close(net.quitc) 559 } 560 561 //重置重置所有网络属性: 562 //清空节点和连接列表 563 func (net *Network) Reset() { 564 net.lock.Lock() 565 defer net.lock.Unlock() 566 567 //重新初始化映射 568 net.connMap = make(map[string]int) 569 net.nodeMap = make(map[enode.ID]int) 570 571 net.Nodes = nil 572 net.Conns = nil 573 } 574 575 //node是围绕adapters.node的包装器,用于跟踪状态 576 //网络中节点的 577 type Node struct { 578 adapters.Node `json:"-"` 579 580 //如果用于创建节点的配置 581 Config *adapters.NodeConfig `json:"config"` 582 583 //向上跟踪节点是否正在运行 584 Up bool `json:"up"` 585 } 586 587 //ID返回节点的ID 588 func (n *Node) ID() enode.ID { 589 return n.Config.ID 590 } 591 592 //字符串返回日志友好的字符串 593 func (n *Node) String() string { 594 return fmt.Sprintf("Node %v", n.ID().TerminalString()) 595 } 596 597 //nodeinfo返回有关节点的信息 598 func (n *Node) NodeInfo() *p2p.NodeInfo { 599 //如果节点尚未启动,请避免出现恐慌。 600 if n.Node == nil { 601 return nil 602 } 603 info := n.Node.NodeInfo() 604 info.Name = n.Config.Name 605 return info 606 } 607 608 //marshaljson实现json.marshaler接口,以便 609 //json包括nodeinfo 610 func (n *Node) MarshalJSON() ([]byte, error) { 611 return json.Marshal(struct { 612 Info *p2p.NodeInfo `json:"info,omitempty"` 613 Config *adapters.NodeConfig `json:"config,omitempty"` 614 Up bool `json:"up"` 615 }{ 616 Info: n.NodeInfo(), 617 Config: n.Config, 618 Up: n.Up, 619 }) 620 } 621 622 //conn表示网络中两个节点之间的连接 623 type Conn struct { 624 //一个是启动连接的节点 625 One enode.ID `json:"one"` 626 627 //另一个是连接到的节点 628 Other enode.ID `json:"other"` 629 630 //向上跟踪连接是否处于活动状态 631 Up bool `json:"up"` 632 //当连接被抓取拨号时注册 633 initiated time.Time 634 635 one *Node 636 other *Node 637 } 638 639 //nodes up返回两个节点当前是否都已启动 640 func (c *Conn) nodesUp() error { 641 if !c.one.Up { 642 return fmt.Errorf("one %v is not up", c.One) 643 } 644 if !c.other.Up { 645 return fmt.Errorf("other %v is not up", c.Other) 646 } 647 return nil 648 } 649 650 //字符串返回日志友好的字符串 651 func (c *Conn) String() string { 652 return fmt.Sprintf("Conn %v->%v", c.One.TerminalString(), c.Other.TerminalString()) 653 } 654 655 //msg表示网络中两个节点之间发送的P2P消息 656 type Msg struct { 657 One enode.ID `json:"one"` 658 Other enode.ID `json:"other"` 659 Protocol string `json:"protocol"` 660 Code uint64 `json:"code"` 661 Received bool `json:"received"` 662 } 663 664 //字符串返回日志友好的字符串 665 func (m *Msg) String() string { 666 return fmt.Sprintf("Msg(%d) %v->%v", m.Code, m.One.TerminalString(), m.Other.TerminalString()) 667 } 668 669 //connlabel生成表示连接的确定字符串 670 //两个节点之间,用于比较两个连接是否相同 671 //结点 672 func ConnLabel(source, target enode.ID) string { 673 var first, second enode.ID 674 if bytes.Compare(source.Bytes(), target.Bytes()) > 0 { 675 first = target 676 second = source 677 } else { 678 first = source 679 second = target 680 } 681 return fmt.Sprintf("%v-%v", first, second) 682 } 683 684 //快照表示网络在单个时间点的状态,可以 685 //用于恢复网络状态 686 type Snapshot struct { 687 Nodes []NodeSnapshot `json:"nodes,omitempty"` 688 Conns []Conn `json:"conns,omitempty"` 689 } 690 691 //nodesnapshot表示网络中节点的状态 692 type NodeSnapshot struct { 693 Node Node `json:"node,omitempty"` 694 695 //快照是从调用节点收集的任意数据。快照() 696 Snapshots map[string][]byte `json:"snapshots,omitempty"` 697 } 698 699 //快照创建网络快照 700 func (net *Network) Snapshot() (*Snapshot, error) { 701 return net.snapshot(nil, nil) 702 } 703 704 func (net *Network) SnapshotWithServices(addServices []string, removeServices []string) (*Snapshot, error) { 705 return net.snapshot(addServices, removeServices) 706 } 707 708 func (net *Network) snapshot(addServices []string, removeServices []string) (*Snapshot, error) { 709 net.lock.Lock() 710 defer net.lock.Unlock() 711 snap := &Snapshot{ 712 Nodes: make([]NodeSnapshot, len(net.Nodes)), 713 } 714 for i, node := range net.Nodes { 715 snap.Nodes[i] = NodeSnapshot{Node: *node} 716 if !node.Up { 717 continue 718 } 719 snapshots, err := node.Snapshots() 720 if err != nil { 721 return nil, err 722 } 723 snap.Nodes[i].Snapshots = snapshots 724 for _, addSvc := range addServices { 725 haveSvc := false 726 for _, svc := range snap.Nodes[i].Node.Config.Services { 727 if svc == addSvc { 728 haveSvc = true 729 break 730 } 731 } 732 if !haveSvc { 733 snap.Nodes[i].Node.Config.Services = append(snap.Nodes[i].Node.Config.Services, addSvc) 734 } 735 } 736 if len(removeServices) > 0 { 737 var cleanedServices []string 738 for _, svc := range snap.Nodes[i].Node.Config.Services { 739 haveSvc := false 740 for _, rmSvc := range removeServices { 741 if rmSvc == svc { 742 haveSvc = true 743 break 744 } 745 } 746 if !haveSvc { 747 cleanedServices = append(cleanedServices, svc) 748 } 749 750 } 751 snap.Nodes[i].Node.Config.Services = cleanedServices 752 } 753 } 754 for _, conn := range net.Conns { 755 if conn.Up { 756 snap.Conns = append(snap.Conns, *conn) 757 } 758 } 759 return snap, nil 760 } 761 762 var snapshotLoadTimeout = 120 * time.Second 763 764 //加载加载网络快照 765 func (net *Network) Load(snap *Snapshot) error { 766 //启动节点。 767 for _, n := range snap.Nodes { 768 if _, err := net.NewNodeWithConfig(n.Node.Config); err != nil { 769 return err 770 } 771 if !n.Node.Up { 772 continue 773 } 774 if err := net.startWithSnapshots(n.Node.Config.ID, n.Snapshots); err != nil { 775 return err 776 } 777 } 778 779 //准备连接事件计数器。 780 allConnected := make(chan struct{}) //建立所有连接时关闭 781 done := make(chan struct{}) //确保事件循环goroutine已终止 782 defer close(done) 783 784 //订阅事件通道。 785 //它需要在事件循环Goroutine之外完成(创建于下面) 786 //以确保在进行连接调用之前事件通道被阻塞。 787 events := make(chan *Event) 788 sub := net.Events().Subscribe(events) 789 defer sub.Unsubscribe() 790 791 go func() { 792 //预期的连接数。 793 total := len(snap.Conns) 794 //从快照建立的所有连接的集合,而不是其他连接。 795 //键数组元素0是连接一个字段值,元素1连接另一个字段。 796 connections := make(map[[2]enode.ID]struct{}, total) 797 798 for { 799 select { 800 case e := <-events: 801 //忽略控件事件,因为它们不表示 802 //连接或断开(向上)状态更改。 803 if e.Control { 804 continue 805 } 806 //仅检测连接事件。 807 if e.Type != EventTypeConn { 808 continue 809 } 810 connection := [2]enode.ID{e.Conn.One, e.Conn.Other} 811 //节点仍然未连接或已断开连接。 812 if !e.Conn.Up { 813 //从已建立的连接集中删除连接。 814 //这样可以防止断开时出现假阳性。 815 delete(connections, connection) 816 log.Warn("load snapshot: unexpected disconnection", "one", e.Conn.One, "other", e.Conn.Other) 817 continue 818 } 819 //检查连接是否来自快照。 820 for _, conn := range snap.Conns { 821 if conn.One == e.Conn.One && conn.Other == e.Conn.Other { 822 //将连接添加到已建立的连接集。 823 connections[connection] = struct{}{} 824 if len(connections) == total { 825 //所有节点都已连接的信号。 826 close(allConnected) 827 return 828 } 829 830 break 831 } 832 } 833 case <-done: 834 //加载函数返回,终止此goroutine。 835 return 836 } 837 } 838 }() 839 840 //开始连接。 841 for _, conn := range snap.Conns { 842 843 if !net.GetNode(conn.One).Up || !net.GetNode(conn.Other).Up { 844 //在这种情况下,连接的至少一个节点没有启动, 845 //所以会导致快照“加载”失败 846 continue 847 } 848 if err := net.Connect(conn.One, conn.Other); err != nil { 849 return err 850 } 851 } 852 853 select { 854 //等待快照的所有连接建立。 855 case <-allConnected: 856 //确保我们不会永远等待。 857 case <-time.After(snapshotLoadTimeout): 858 return errors.New("snapshot connections not established") 859 } 860 return nil 861 } 862 863 //订阅从通道读取控制事件并执行它们 864 func (net *Network) Subscribe(events chan *Event) { 865 for { 866 select { 867 case event, ok := <-events: 868 if !ok { 869 return 870 } 871 if event.Control { 872 net.executeControlEvent(event) 873 } 874 case <-net.quitc: 875 return 876 } 877 } 878 } 879 880 func (net *Network) executeControlEvent(event *Event) { 881 log.Trace("Executing control event", "type", event.Type, "event", event) 882 switch event.Type { 883 case EventTypeNode: 884 if err := net.executeNodeEvent(event); err != nil { 885 log.Error("Error executing node event", "event", event, "err", err) 886 } 887 case EventTypeConn: 888 if err := net.executeConnEvent(event); err != nil { 889 log.Error("Error executing conn event", "event", event, "err", err) 890 } 891 case EventTypeMsg: 892 log.Warn("Ignoring control msg event") 893 } 894 } 895 896 func (net *Network) executeNodeEvent(e *Event) error { 897 if !e.Node.Up { 898 return net.Stop(e.Node.ID()) 899 } 900 901 if _, err := net.NewNodeWithConfig(e.Node.Config); err != nil { 902 return err 903 } 904 return net.Start(e.Node.ID()) 905 } 906 907 func (net *Network) executeConnEvent(e *Event) error { 908 if e.Conn.Up { 909 return net.Connect(e.Conn.One, e.Conn.Other) 910 } else { 911 return net.Disconnect(e.Conn.One, e.Conn.Other) 912 } 913 } 914