github.com/waltonchain/waltonchain_gwtc_src@v1.1.4-0.20201225072101-8a298c95a819/p2p/simulations/network.go (about) 1 // Copyright 2017 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-wtc library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-wtc library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package simulations 18 19 import ( 20 "bytes" 21 "context" 22 "encoding/json" 23 "fmt" 24 "sync" 25 26 "github.com/wtc/go-wtc/event" 27 "github.com/wtc/go-wtc/log" 28 "github.com/wtc/go-wtc/p2p" 29 "github.com/wtc/go-wtc/p2p/discover" 30 "github.com/wtc/go-wtc/p2p/simulations/adapters" 31 ) 32 33 // NetworkConfig defines configuration options for starting a Network 34 type NetworkConfig struct { 35 ID string `json:"id"` 36 DefaultService string `json:"default_service,omitempty"` 37 } 38 39 // Network models a p2p simulation network which consists of a collection of 40 // simulated nodes and the connections which exist between them. 41 // 42 // The Network has a single NodeAdapter which is responsible for actually 43 // starting nodes and connecting them together. 44 // 45 // The Network emits events when nodes are started and stopped, when they are 46 // connected and disconnected, and also when messages are sent between nodes. 47 type Network struct { 48 NetworkConfig 49 50 Nodes []*Node `json:"nodes"` 51 nodeMap map[discover.NodeID]int 52 53 Conns []*Conn `json:"conns"` 54 connMap map[string]int 55 56 nodeAdapter adapters.NodeAdapter 57 events event.Feed 58 lock sync.RWMutex 59 quitc chan struct{} 60 } 61 62 // NewNetwork returns a Network which uses the given NodeAdapter and NetworkConfig 63 func NewNetwork(nodeAdapter adapters.NodeAdapter, conf *NetworkConfig) *Network { 64 return &Network{ 65 NetworkConfig: *conf, 66 nodeAdapter: nodeAdapter, 67 nodeMap: make(map[discover.NodeID]int), 68 connMap: make(map[string]int), 69 quitc: make(chan struct{}), 70 } 71 } 72 73 // Events returns the output event feed of the Network. 74 func (self *Network) Events() *event.Feed { 75 return &self.events 76 } 77 78 // NewNode adds a new node to the network with a random ID 79 func (self *Network) NewNode() (*Node, error) { 80 conf := adapters.RandomNodeConfig() 81 conf.Services = []string{self.DefaultService} 82 return self.NewNodeWithConfig(conf) 83 } 84 85 // NewNodeWithConfig adds a new node to the network with the given config, 86 // returning an error if a node with the same ID or name already exists 87 func (self *Network) NewNodeWithConfig(conf *adapters.NodeConfig) (*Node, error) { 88 self.lock.Lock() 89 defer self.lock.Unlock() 90 91 // create a random ID and PrivateKey if not set 92 if conf.ID == (discover.NodeID{}) { 93 c := adapters.RandomNodeConfig() 94 conf.ID = c.ID 95 conf.PrivateKey = c.PrivateKey 96 } 97 id := conf.ID 98 99 // assign a name to the node if not set 100 if conf.Name == "" { 101 conf.Name = fmt.Sprintf("node%02d", len(self.Nodes)+1) 102 } 103 104 // check the node doesn't already exist 105 if node := self.getNode(id); node != nil { 106 return nil, fmt.Errorf("node with ID %q already exists", id) 107 } 108 if node := self.getNodeByName(conf.Name); node != nil { 109 return nil, fmt.Errorf("node with name %q already exists", conf.Name) 110 } 111 112 // if no services are configured, use the default service 113 if len(conf.Services) == 0 { 114 conf.Services = []string{self.DefaultService} 115 } 116 117 // use the NodeAdapter to create the node 118 adapterNode, err := self.nodeAdapter.NewNode(conf) 119 if err != nil { 120 return nil, err 121 } 122 node := &Node{ 123 Node: adapterNode, 124 Config: conf, 125 } 126 log.Trace(fmt.Sprintf("node %v created", id)) 127 self.nodeMap[id] = len(self.Nodes) 128 self.Nodes = append(self.Nodes, node) 129 130 // emit a "control" event 131 self.events.Send(ControlEvent(node)) 132 133 return node, nil 134 } 135 136 // Config returns the network configuration 137 func (self *Network) Config() *NetworkConfig { 138 return &self.NetworkConfig 139 } 140 141 // StartAll starts all nodes in the network 142 func (self *Network) StartAll() error { 143 for _, node := range self.Nodes { 144 if node.Up { 145 continue 146 } 147 if err := self.Start(node.ID()); err != nil { 148 return err 149 } 150 } 151 return nil 152 } 153 154 // StopAll stops all nodes in the network 155 func (self *Network) StopAll() error { 156 for _, node := range self.Nodes { 157 if !node.Up { 158 continue 159 } 160 if err := self.Stop(node.ID()); err != nil { 161 return err 162 } 163 } 164 return nil 165 } 166 167 // Start starts the node with the given ID 168 func (self *Network) Start(id discover.NodeID) error { 169 return self.startWithSnapshots(id, nil) 170 } 171 172 // startWithSnapshots starts the node with the given ID using the give 173 // snapshots 174 func (self *Network) startWithSnapshots(id discover.NodeID, snapshots map[string][]byte) error { 175 node := self.GetNode(id) 176 if node == nil { 177 return fmt.Errorf("node %v does not exist", id) 178 } 179 if node.Up { 180 return fmt.Errorf("node %v already up", id) 181 } 182 log.Trace(fmt.Sprintf("starting node %v: %v using %v", id, node.Up, self.nodeAdapter.Name())) 183 if err := node.Start(snapshots); err != nil { 184 log.Warn(fmt.Sprintf("start up failed: %v", err)) 185 return err 186 } 187 node.Up = true 188 log.Info(fmt.Sprintf("started node %v: %v", id, node.Up)) 189 190 self.events.Send(NewEvent(node)) 191 192 // subscribe to peer events 193 client, err := node.Client() 194 if err != nil { 195 return fmt.Errorf("error getting rpc client for node %v: %s", id, err) 196 } 197 events := make(chan *p2p.PeerEvent) 198 sub, err := client.Subscribe(context.Background(), "admin", events, "peerEvents") 199 if err != nil { 200 return fmt.Errorf("error getting peer events for node %v: %s", id, err) 201 } 202 go self.watchPeerEvents(id, events, sub) 203 return nil 204 } 205 206 // watchPeerEvents reads peer events from the given channel and emits 207 // corresponding network events 208 func (self *Network) watchPeerEvents(id discover.NodeID, events chan *p2p.PeerEvent, sub event.Subscription) { 209 defer func() { 210 sub.Unsubscribe() 211 212 // assume the node is now down 213 self.lock.Lock() 214 node := self.getNode(id) 215 node.Up = false 216 self.lock.Unlock() 217 self.events.Send(NewEvent(node)) 218 }() 219 for { 220 select { 221 case event, ok := <-events: 222 if !ok { 223 return 224 } 225 peer := event.Peer 226 switch event.Type { 227 228 case p2p.PeerEventTypeAdd: 229 self.DidConnect(id, peer) 230 231 case p2p.PeerEventTypeDrop: 232 self.DidDisconnect(id, peer) 233 234 case p2p.PeerEventTypeMsgSend: 235 self.DidSend(id, peer, event.Protocol, *event.MsgCode) 236 237 case p2p.PeerEventTypeMsgRecv: 238 self.DidReceive(peer, id, event.Protocol, *event.MsgCode) 239 240 } 241 242 case err := <-sub.Err(): 243 if err != nil { 244 log.Error(fmt.Sprintf("error getting peer events for node %v", id), "err", err) 245 } 246 return 247 } 248 } 249 } 250 251 // Stop stops the node with the given ID 252 func (self *Network) Stop(id discover.NodeID) error { 253 node := self.GetNode(id) 254 if node == nil { 255 return fmt.Errorf("node %v does not exist", id) 256 } 257 if !node.Up { 258 return fmt.Errorf("node %v already down", id) 259 } 260 if err := node.Stop(); err != nil { 261 return err 262 } 263 node.Up = false 264 log.Info(fmt.Sprintf("stop node %v: %v", id, node.Up)) 265 266 self.events.Send(ControlEvent(node)) 267 return nil 268 } 269 270 // Connect connects two nodes together by calling the "admin_addPeer" RPC 271 // method on the "one" node so that it connects to the "other" node 272 func (self *Network) Connect(oneID, otherID discover.NodeID) error { 273 log.Debug(fmt.Sprintf("connecting %s to %s", oneID, otherID)) 274 conn, err := self.GetOrCreateConn(oneID, otherID) 275 if err != nil { 276 return err 277 } 278 if conn.Up { 279 return fmt.Errorf("%v and %v already connected", oneID, otherID) 280 } 281 if err := conn.nodesUp(); err != nil { 282 return err 283 } 284 client, err := conn.one.Client() 285 if err != nil { 286 return err 287 } 288 self.events.Send(ControlEvent(conn)) 289 return client.Call(nil, "admin_addPeer", string(conn.other.Addr())) 290 } 291 292 // Disconnect disconnects two nodes by calling the "admin_removePeer" RPC 293 // method on the "one" node so that it disconnects from the "other" node 294 func (self *Network) Disconnect(oneID, otherID discover.NodeID) error { 295 conn := self.GetConn(oneID, otherID) 296 if conn == nil { 297 return fmt.Errorf("connection between %v and %v does not exist", oneID, otherID) 298 } 299 if !conn.Up { 300 return fmt.Errorf("%v and %v already disconnected", oneID, otherID) 301 } 302 client, err := conn.one.Client() 303 if err != nil { 304 return err 305 } 306 self.events.Send(ControlEvent(conn)) 307 return client.Call(nil, "admin_removePeer", string(conn.other.Addr())) 308 } 309 310 // DidConnect tracks the fact that the "one" node connected to the "other" node 311 func (self *Network) DidConnect(one, other discover.NodeID) error { 312 conn, err := self.GetOrCreateConn(one, other) 313 if err != nil { 314 return fmt.Errorf("connection between %v and %v does not exist", one, other) 315 } 316 if conn.Up { 317 return fmt.Errorf("%v and %v already connected", one, other) 318 } 319 conn.Up = true 320 self.events.Send(NewEvent(conn)) 321 return nil 322 } 323 324 // DidDisconnect tracks the fact that the "one" node disconnected from the 325 // "other" node 326 func (self *Network) DidDisconnect(one, other discover.NodeID) error { 327 conn, err := self.GetOrCreateConn(one, other) 328 if err != nil { 329 return fmt.Errorf("connection between %v and %v does not exist", one, other) 330 } 331 if !conn.Up { 332 return fmt.Errorf("%v and %v already disconnected", one, other) 333 } 334 conn.Up = false 335 self.events.Send(NewEvent(conn)) 336 return nil 337 } 338 339 // DidSend tracks the fact that "sender" sent a message to "receiver" 340 func (self *Network) DidSend(sender, receiver discover.NodeID, proto string, code uint64) error { 341 msg := &Msg{ 342 One: sender, 343 Other: receiver, 344 Protocol: proto, 345 Code: code, 346 Received: false, 347 } 348 self.events.Send(NewEvent(msg)) 349 return nil 350 } 351 352 // DidReceive tracks the fact that "receiver" received a message from "sender" 353 func (self *Network) DidReceive(sender, receiver discover.NodeID, proto string, code uint64) error { 354 msg := &Msg{ 355 One: sender, 356 Other: receiver, 357 Protocol: proto, 358 Code: code, 359 Received: true, 360 } 361 self.events.Send(NewEvent(msg)) 362 return nil 363 } 364 365 // GetNode gets the node with the given ID, returning nil if the node does not 366 // exist 367 func (self *Network) GetNode(id discover.NodeID) *Node { 368 self.lock.Lock() 369 defer self.lock.Unlock() 370 return self.getNode(id) 371 } 372 373 // GetNode gets the node with the given name, returning nil if the node does 374 // not exist 375 func (self *Network) GetNodeByName(name string) *Node { 376 self.lock.Lock() 377 defer self.lock.Unlock() 378 return self.getNodeByName(name) 379 } 380 381 func (self *Network) getNode(id discover.NodeID) *Node { 382 i, found := self.nodeMap[id] 383 if !found { 384 return nil 385 } 386 return self.Nodes[i] 387 } 388 389 func (self *Network) getNodeByName(name string) *Node { 390 for _, node := range self.Nodes { 391 if node.Config.Name == name { 392 return node 393 } 394 } 395 return nil 396 } 397 398 // GetNodes returns the existing nodes 399 func (self *Network) GetNodes() []*Node { 400 self.lock.Lock() 401 defer self.lock.Unlock() 402 return self.Nodes 403 } 404 405 // GetConn returns the connection which exists between "one" and "other" 406 // regardless of which node initiated the connection 407 func (self *Network) GetConn(oneID, otherID discover.NodeID) *Conn { 408 self.lock.Lock() 409 defer self.lock.Unlock() 410 return self.getConn(oneID, otherID) 411 } 412 413 // GetOrCreateConn is like GetConn but creates the connection if it doesn't 414 // already exist 415 func (self *Network) GetOrCreateConn(oneID, otherID discover.NodeID) (*Conn, error) { 416 self.lock.Lock() 417 defer self.lock.Unlock() 418 if conn := self.getConn(oneID, otherID); conn != nil { 419 return conn, nil 420 } 421 422 one := self.getNode(oneID) 423 if one == nil { 424 return nil, fmt.Errorf("node %v does not exist", oneID) 425 } 426 other := self.getNode(otherID) 427 if other == nil { 428 return nil, fmt.Errorf("node %v does not exist", otherID) 429 } 430 conn := &Conn{ 431 One: oneID, 432 Other: otherID, 433 one: one, 434 other: other, 435 } 436 label := ConnLabel(oneID, otherID) 437 self.connMap[label] = len(self.Conns) 438 self.Conns = append(self.Conns, conn) 439 return conn, nil 440 } 441 442 func (self *Network) getConn(oneID, otherID discover.NodeID) *Conn { 443 label := ConnLabel(oneID, otherID) 444 i, found := self.connMap[label] 445 if !found { 446 return nil 447 } 448 return self.Conns[i] 449 } 450 451 // Shutdown stops all nodes in the network and closes the quit channel 452 func (self *Network) Shutdown() { 453 for _, node := range self.Nodes { 454 log.Debug(fmt.Sprintf("stopping node %s", node.ID().TerminalString())) 455 if err := node.Stop(); err != nil { 456 log.Warn(fmt.Sprintf("error stopping node %s", node.ID().TerminalString()), "err", err) 457 } 458 } 459 close(self.quitc) 460 } 461 462 // Node is a wrapper around adapters.Node which is used to track the status 463 // of a node in the network 464 type Node struct { 465 adapters.Node `json:"-"` 466 467 // Config if the config used to created the node 468 Config *adapters.NodeConfig `json:"config"` 469 470 // Up tracks whether or not the node is running 471 Up bool `json:"up"` 472 } 473 474 // ID returns the ID of the node 475 func (self *Node) ID() discover.NodeID { 476 return self.Config.ID 477 } 478 479 // String returns a log-friendly string 480 func (self *Node) String() string { 481 return fmt.Sprintf("Node %v", self.ID().TerminalString()) 482 } 483 484 // NodeInfo returns information about the node 485 func (self *Node) NodeInfo() *p2p.NodeInfo { 486 // avoid a panic if the node is not started yet 487 if self.Node == nil { 488 return nil 489 } 490 info := self.Node.NodeInfo() 491 info.Name = self.Config.Name 492 return info 493 } 494 495 // MarshalJSON implements the json.Marshaler interface so that the encoded 496 // JSON includes the NodeInfo 497 func (self *Node) MarshalJSON() ([]byte, error) { 498 return json.Marshal(struct { 499 Info *p2p.NodeInfo `json:"info,omitempty"` 500 Config *adapters.NodeConfig `json:"config,omitempty"` 501 Up bool `json:"up"` 502 }{ 503 Info: self.NodeInfo(), 504 Config: self.Config, 505 Up: self.Up, 506 }) 507 } 508 509 // Conn represents a connection between two nodes in the network 510 type Conn struct { 511 // One is the node which initiated the connection 512 One discover.NodeID `json:"one"` 513 514 // Other is the node which the connection was made to 515 Other discover.NodeID `json:"other"` 516 517 // Up tracks whether or not the connection is active 518 Up bool `json:"up"` 519 520 one *Node 521 other *Node 522 } 523 524 // nodesUp returns whether both nodes are currently up 525 func (self *Conn) nodesUp() error { 526 if !self.one.Up { 527 return fmt.Errorf("one %v is not up", self.One) 528 } 529 if !self.other.Up { 530 return fmt.Errorf("other %v is not up", self.Other) 531 } 532 return nil 533 } 534 535 // String returns a log-friendly string 536 func (self *Conn) String() string { 537 return fmt.Sprintf("Conn %v->%v", self.One.TerminalString(), self.Other.TerminalString()) 538 } 539 540 // Msg represents a p2p message sent between two nodes in the network 541 type Msg struct { 542 One discover.NodeID `json:"one"` 543 Other discover.NodeID `json:"other"` 544 Protocol string `json:"protocol"` 545 Code uint64 `json:"code"` 546 Received bool `json:"received"` 547 } 548 549 // String returns a log-friendly string 550 func (self *Msg) String() string { 551 return fmt.Sprintf("Msg(%d) %v->%v", self.Code, self.One.TerminalString(), self.Other.TerminalString()) 552 } 553 554 // ConnLabel generates a deterministic string which represents a connection 555 // between two nodes, used to compare if two connections are between the same 556 // nodes 557 func ConnLabel(source, target discover.NodeID) string { 558 var first, second discover.NodeID 559 if bytes.Compare(source.Bytes(), target.Bytes()) > 0 { 560 first = target 561 second = source 562 } else { 563 first = source 564 second = target 565 } 566 return fmt.Sprintf("%v-%v", first, second) 567 } 568 569 // Snapshot represents the state of a network at a single point in time and can 570 // be used to restore the state of a network 571 type Snapshot struct { 572 Nodes []NodeSnapshot `json:"nodes,omitempty"` 573 Conns []Conn `json:"conns,omitempty"` 574 } 575 576 // NodeSnapshot represents the state of a node in the network 577 type NodeSnapshot struct { 578 Node Node `json:"node,omitempty"` 579 580 // Snapshots is arbitrary data gathered from calling node.Snapshots() 581 Snapshots map[string][]byte `json:"snapshots,omitempty"` 582 } 583 584 // Snapshot creates a network snapshot 585 func (self *Network) Snapshot() (*Snapshot, error) { 586 self.lock.Lock() 587 defer self.lock.Unlock() 588 snap := &Snapshot{ 589 Nodes: make([]NodeSnapshot, len(self.Nodes)), 590 Conns: make([]Conn, len(self.Conns)), 591 } 592 for i, node := range self.Nodes { 593 snap.Nodes[i] = NodeSnapshot{Node: *node} 594 if !node.Up { 595 continue 596 } 597 snapshots, err := node.Snapshots() 598 if err != nil { 599 return nil, err 600 } 601 snap.Nodes[i].Snapshots = snapshots 602 } 603 for i, conn := range self.Conns { 604 snap.Conns[i] = *conn 605 } 606 return snap, nil 607 } 608 609 // Load loads a network snapshot 610 func (self *Network) Load(snap *Snapshot) error { 611 for _, n := range snap.Nodes { 612 if _, err := self.NewNodeWithConfig(n.Node.Config); err != nil { 613 return err 614 } 615 if !n.Node.Up { 616 continue 617 } 618 if err := self.startWithSnapshots(n.Node.Config.ID, n.Snapshots); err != nil { 619 return err 620 } 621 } 622 for _, conn := range snap.Conns { 623 if err := self.Connect(conn.One, conn.Other); err != nil { 624 return err 625 } 626 } 627 return nil 628 } 629 630 // Subscribe reads control events from a channel and executes them 631 func (self *Network) Subscribe(events chan *Event) { 632 for { 633 select { 634 case event, ok := <-events: 635 if !ok { 636 return 637 } 638 if event.Control { 639 self.executeControlEvent(event) 640 } 641 case <-self.quitc: 642 return 643 } 644 } 645 } 646 647 func (self *Network) executeControlEvent(event *Event) { 648 log.Trace("execute control event", "type", event.Type, "event", event) 649 switch event.Type { 650 case EventTypeNode: 651 if err := self.executeNodeEvent(event); err != nil { 652 log.Error("error executing node event", "event", event, "err", err) 653 } 654 case EventTypeConn: 655 if err := self.executeConnEvent(event); err != nil { 656 log.Error("error executing conn event", "event", event, "err", err) 657 } 658 case EventTypeMsg: 659 log.Warn("ignoring control msg event") 660 } 661 } 662 663 func (self *Network) executeNodeEvent(e *Event) error { 664 if !e.Node.Up { 665 return self.Stop(e.Node.ID()) 666 } 667 668 if _, err := self.NewNodeWithConfig(e.Node.Config); err != nil { 669 return err 670 } 671 return self.Start(e.Node.ID()) 672 } 673 674 func (self *Network) executeConnEvent(e *Event) error { 675 if e.Conn.Up { 676 return self.Connect(e.Conn.One, e.Conn.Other) 677 } else { 678 return self.Disconnect(e.Conn.One, e.Conn.Other) 679 } 680 }