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