github.com/theQRL/go-zond@v0.1.1/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-ethereum 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-ethereum 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 "errors" 24 "fmt" 25 "math/rand" 26 "sync" 27 "time" 28 29 "github.com/theQRL/go-zond/event" 30 "github.com/theQRL/go-zond/log" 31 "github.com/theQRL/go-zond/p2p" 32 "github.com/theQRL/go-zond/p2p/enode" 33 "github.com/theQRL/go-zond/p2p/simulations/adapters" 34 ) 35 36 var DialBanTimeout = 200 * time.Millisecond 37 38 // NetworkConfig defines configuration options for starting a Network 39 type NetworkConfig struct { 40 ID string `json:"id"` 41 DefaultService string `json:"default_service,omitempty"` 42 } 43 44 // Network models a p2p simulation network which consists of a collection of 45 // simulated nodes and the connections which exist between them. 46 // 47 // The Network has a single NodeAdapter which is responsible for actually 48 // starting nodes and connecting them together. 49 // 50 // The Network emits events when nodes are started and stopped, when they are 51 // connected and disconnected, and also when messages are sent between nodes. 52 type Network struct { 53 NetworkConfig 54 55 Nodes []*Node `json:"nodes"` 56 nodeMap map[enode.ID]int 57 58 // Maps a node property string to node indexes of all nodes that hold this property 59 propertyMap map[string][]int 60 61 Conns []*Conn `json:"conns"` 62 connMap map[string]int 63 64 nodeAdapter adapters.NodeAdapter 65 events event.Feed 66 lock sync.RWMutex 67 quitc chan struct{} 68 } 69 70 // NewNetwork returns a Network which uses the given NodeAdapter and NetworkConfig 71 func NewNetwork(nodeAdapter adapters.NodeAdapter, conf *NetworkConfig) *Network { 72 return &Network{ 73 NetworkConfig: *conf, 74 nodeAdapter: nodeAdapter, 75 nodeMap: make(map[enode.ID]int), 76 propertyMap: make(map[string][]int), 77 connMap: make(map[string]int), 78 quitc: make(chan struct{}), 79 } 80 } 81 82 // Events returns the output event feed of the Network. 83 func (net *Network) Events() *event.Feed { 84 return &net.events 85 } 86 87 // NewNodeWithConfig adds a new node to the network with the given config, 88 // returning an error if a node with the same ID or name already exists 89 func (net *Network) NewNodeWithConfig(conf *adapters.NodeConfig) (*Node, error) { 90 net.lock.Lock() 91 defer net.lock.Unlock() 92 93 if conf.Reachable == nil { 94 conf.Reachable = func(otherID enode.ID) bool { 95 _, err := net.InitConn(conf.ID, otherID) 96 if err != nil && bytes.Compare(conf.ID.Bytes(), otherID.Bytes()) < 0 { 97 return false 98 } 99 return true 100 } 101 } 102 103 // check the node doesn't already exist 104 if node := net.getNode(conf.ID); node != nil { 105 return nil, fmt.Errorf("node with ID %q already exists", conf.ID) 106 } 107 if node := net.getNodeByName(conf.Name); node != nil { 108 return nil, fmt.Errorf("node with name %q already exists", conf.Name) 109 } 110 111 // if no services are configured, use the default service 112 if len(conf.Lifecycles) == 0 { 113 conf.Lifecycles = []string{net.DefaultService} 114 } 115 116 // use the NodeAdapter to create the node 117 adapterNode, err := net.nodeAdapter.NewNode(conf) 118 if err != nil { 119 return nil, err 120 } 121 node := newNode(adapterNode, conf, false) 122 log.Trace("Node created", "id", conf.ID) 123 124 nodeIndex := len(net.Nodes) 125 net.nodeMap[conf.ID] = nodeIndex 126 net.Nodes = append(net.Nodes, node) 127 128 // Register any node properties with the network-level propertyMap 129 for _, property := range conf.Properties { 130 net.propertyMap[property] = append(net.propertyMap[property], nodeIndex) 131 } 132 133 // emit a "control" event 134 net.events.Send(ControlEvent(node)) 135 136 return node, nil 137 } 138 139 // Config returns the network configuration 140 func (net *Network) Config() *NetworkConfig { 141 return &net.NetworkConfig 142 } 143 144 // StartAll starts all nodes in the network 145 func (net *Network) StartAll() error { 146 for _, node := range net.Nodes { 147 if node.Up() { 148 continue 149 } 150 if err := net.Start(node.ID()); err != nil { 151 return err 152 } 153 } 154 return nil 155 } 156 157 // StopAll stops all nodes in the network 158 func (net *Network) StopAll() error { 159 for _, node := range net.Nodes { 160 if !node.Up() { 161 continue 162 } 163 if err := net.Stop(node.ID()); err != nil { 164 return err 165 } 166 } 167 return nil 168 } 169 170 // Start starts the node with the given ID 171 func (net *Network) Start(id enode.ID) error { 172 return net.startWithSnapshots(id, nil) 173 } 174 175 // startWithSnapshots starts the node with the given ID using the give 176 // snapshots 177 func (net *Network) startWithSnapshots(id enode.ID, snapshots map[string][]byte) error { 178 net.lock.Lock() 179 defer net.lock.Unlock() 180 181 node := net.getNode(id) 182 if node == nil { 183 return fmt.Errorf("node %v does not exist", id) 184 } 185 if node.Up() { 186 return fmt.Errorf("node %v already up", id) 187 } 188 log.Trace("Starting node", "id", id, "adapter", net.nodeAdapter.Name()) 189 if err := node.Start(snapshots); err != nil { 190 log.Warn("Node startup failed", "id", id, "err", err) 191 return err 192 } 193 node.SetUp(true) 194 log.Info("Started node", "id", id) 195 ev := NewEvent(node) 196 net.events.Send(ev) 197 198 // subscribe to peer events 199 client, err := node.Client() 200 if err != nil { 201 return fmt.Errorf("error getting rpc client for node %v: %s", id, err) 202 } 203 events := make(chan *p2p.PeerEvent) 204 sub, err := client.Subscribe(context.Background(), "admin", events, "peerEvents") 205 if err != nil { 206 return fmt.Errorf("error getting peer events for node %v: %s", id, err) 207 } 208 go net.watchPeerEvents(id, events, sub) 209 return nil 210 } 211 212 // watchPeerEvents reads peer events from the given channel and emits 213 // corresponding network events 214 func (net *Network) watchPeerEvents(id enode.ID, events chan *p2p.PeerEvent, sub event.Subscription) { 215 defer func() { 216 sub.Unsubscribe() 217 218 // assume the node is now down 219 net.lock.Lock() 220 defer net.lock.Unlock() 221 222 node := net.getNode(id) 223 if node == nil { 224 return 225 } 226 node.SetUp(false) 227 ev := NewEvent(node) 228 net.events.Send(ev) 229 }() 230 for { 231 select { 232 case event, ok := <-events: 233 if !ok { 234 return 235 } 236 peer := event.Peer 237 switch event.Type { 238 case p2p.PeerEventTypeAdd: 239 net.DidConnect(id, peer) 240 241 case p2p.PeerEventTypeDrop: 242 net.DidDisconnect(id, peer) 243 244 case p2p.PeerEventTypeMsgSend: 245 net.DidSend(id, peer, event.Protocol, *event.MsgCode) 246 247 case p2p.PeerEventTypeMsgRecv: 248 net.DidReceive(peer, id, event.Protocol, *event.MsgCode) 249 } 250 251 case err := <-sub.Err(): 252 if err != nil { 253 log.Error("Error in peer event subscription", "id", id, "err", err) 254 } 255 return 256 } 257 } 258 } 259 260 // Stop stops the node with the given ID 261 func (net *Network) Stop(id enode.ID) error { 262 // IMPORTANT: node.Stop() must NOT be called under net.lock as 263 // node.Reachable() closure has a reference to the network and 264 // calls net.InitConn() what also locks the network. => DEADLOCK 265 // That holds until the following ticket is not resolved: 266 267 var err error 268 269 node, err := func() (*Node, error) { 270 net.lock.Lock() 271 defer net.lock.Unlock() 272 273 node := net.getNode(id) 274 if node == nil { 275 return nil, fmt.Errorf("node %v does not exist", id) 276 } 277 if !node.Up() { 278 return nil, fmt.Errorf("node %v already down", id) 279 } 280 node.SetUp(false) 281 return node, nil 282 }() 283 if err != nil { 284 return err 285 } 286 287 err = node.Stop() // must be called without net.lock 288 289 net.lock.Lock() 290 defer net.lock.Unlock() 291 292 if err != nil { 293 node.SetUp(true) 294 return err 295 } 296 log.Info("Stopped node", "id", id, "err", err) 297 ev := ControlEvent(node) 298 net.events.Send(ev) 299 return nil 300 } 301 302 // Connect connects two nodes together by calling the "admin_addPeer" RPC 303 // method on the "one" node so that it connects to the "other" node 304 func (net *Network) Connect(oneID, otherID enode.ID) error { 305 net.lock.Lock() 306 defer net.lock.Unlock() 307 return net.connect(oneID, otherID) 308 } 309 310 func (net *Network) connect(oneID, otherID enode.ID) error { 311 log.Debug("Connecting nodes with addPeer", "id", oneID, "other", otherID) 312 conn, err := net.initConn(oneID, otherID) 313 if err != nil { 314 return err 315 } 316 client, err := conn.one.Client() 317 if err != nil { 318 return err 319 } 320 net.events.Send(ControlEvent(conn)) 321 return client.Call(nil, "admin_addPeer", string(conn.other.Addr())) 322 } 323 324 // Disconnect disconnects two nodes by calling the "admin_removePeer" RPC 325 // method on the "one" node so that it disconnects from the "other" node 326 func (net *Network) Disconnect(oneID, otherID enode.ID) error { 327 conn := net.GetConn(oneID, otherID) 328 if conn == nil { 329 return fmt.Errorf("connection between %v and %v does not exist", oneID, otherID) 330 } 331 if !conn.Up { 332 return fmt.Errorf("%v and %v already disconnected", oneID, otherID) 333 } 334 client, err := conn.one.Client() 335 if err != nil { 336 return err 337 } 338 net.events.Send(ControlEvent(conn)) 339 return client.Call(nil, "admin_removePeer", string(conn.other.Addr())) 340 } 341 342 // DidConnect tracks the fact that the "one" node connected to the "other" node 343 func (net *Network) DidConnect(one, other enode.ID) error { 344 net.lock.Lock() 345 defer net.lock.Unlock() 346 conn, err := net.getOrCreateConn(one, other) 347 if err != nil { 348 return fmt.Errorf("connection between %v and %v does not exist", one, other) 349 } 350 if conn.Up { 351 return fmt.Errorf("%v and %v already connected", one, other) 352 } 353 conn.Up = true 354 net.events.Send(NewEvent(conn)) 355 return nil 356 } 357 358 // DidDisconnect tracks the fact that the "one" node disconnected from the 359 // "other" node 360 func (net *Network) DidDisconnect(one, other enode.ID) error { 361 net.lock.Lock() 362 defer net.lock.Unlock() 363 conn := net.getConn(one, other) 364 if conn == nil { 365 return fmt.Errorf("connection between %v and %v does not exist", one, other) 366 } 367 if !conn.Up { 368 return fmt.Errorf("%v and %v already disconnected", one, other) 369 } 370 conn.Up = false 371 conn.initiated = time.Now().Add(-DialBanTimeout) 372 net.events.Send(NewEvent(conn)) 373 return nil 374 } 375 376 // DidSend tracks the fact that "sender" sent a message to "receiver" 377 func (net *Network) DidSend(sender, receiver enode.ID, proto string, code uint64) error { 378 msg := &Msg{ 379 One: sender, 380 Other: receiver, 381 Protocol: proto, 382 Code: code, 383 Received: false, 384 } 385 net.events.Send(NewEvent(msg)) 386 return nil 387 } 388 389 // DidReceive tracks the fact that "receiver" received a message from "sender" 390 func (net *Network) DidReceive(sender, receiver enode.ID, proto string, code uint64) error { 391 msg := &Msg{ 392 One: sender, 393 Other: receiver, 394 Protocol: proto, 395 Code: code, 396 Received: true, 397 } 398 net.events.Send(NewEvent(msg)) 399 return nil 400 } 401 402 // GetNode gets the node with the given ID, returning nil if the node does not 403 // exist 404 func (net *Network) GetNode(id enode.ID) *Node { 405 net.lock.RLock() 406 defer net.lock.RUnlock() 407 return net.getNode(id) 408 } 409 410 func (net *Network) getNode(id enode.ID) *Node { 411 i, found := net.nodeMap[id] 412 if !found { 413 return nil 414 } 415 return net.Nodes[i] 416 } 417 418 // GetNodeByName gets the node with the given name, returning nil if the node does 419 // not exist 420 func (net *Network) GetNodeByName(name string) *Node { 421 net.lock.RLock() 422 defer net.lock.RUnlock() 423 return net.getNodeByName(name) 424 } 425 426 func (net *Network) getNodeByName(name string) *Node { 427 for _, node := range net.Nodes { 428 if node.Config.Name == name { 429 return node 430 } 431 } 432 return nil 433 } 434 435 // GetNodeIDs returns the IDs of all existing nodes 436 // Nodes can optionally be excluded by specifying their enode.ID. 437 func (net *Network) GetNodeIDs(excludeIDs ...enode.ID) []enode.ID { 438 net.lock.RLock() 439 defer net.lock.RUnlock() 440 441 return net.getNodeIDs(excludeIDs) 442 } 443 444 func (net *Network) getNodeIDs(excludeIDs []enode.ID) []enode.ID { 445 // Get all current nodeIDs 446 nodeIDs := make([]enode.ID, 0, len(net.nodeMap)) 447 for id := range net.nodeMap { 448 nodeIDs = append(nodeIDs, id) 449 } 450 451 if len(excludeIDs) > 0 { 452 // Return the difference of nodeIDs and excludeIDs 453 return filterIDs(nodeIDs, excludeIDs) 454 } 455 return nodeIDs 456 } 457 458 // GetNodes returns the existing nodes. 459 // Nodes can optionally be excluded by specifying their enode.ID. 460 func (net *Network) GetNodes(excludeIDs ...enode.ID) []*Node { 461 net.lock.RLock() 462 defer net.lock.RUnlock() 463 464 return net.getNodes(excludeIDs) 465 } 466 467 func (net *Network) getNodes(excludeIDs []enode.ID) []*Node { 468 if len(excludeIDs) > 0 { 469 nodeIDs := net.getNodeIDs(excludeIDs) 470 return net.getNodesByID(nodeIDs) 471 } 472 return net.Nodes 473 } 474 475 // GetNodesByID returns existing nodes with the given enode.IDs. 476 // If a node doesn't exist with a given enode.ID, it is ignored. 477 func (net *Network) GetNodesByID(nodeIDs []enode.ID) []*Node { 478 net.lock.RLock() 479 defer net.lock.RUnlock() 480 481 return net.getNodesByID(nodeIDs) 482 } 483 484 func (net *Network) getNodesByID(nodeIDs []enode.ID) []*Node { 485 nodes := make([]*Node, 0, len(nodeIDs)) 486 for _, id := range nodeIDs { 487 node := net.getNode(id) 488 if node != nil { 489 nodes = append(nodes, node) 490 } 491 } 492 493 return nodes 494 } 495 496 // GetNodesByProperty returns existing nodes that have the given property string registered in their NodeConfig 497 func (net *Network) GetNodesByProperty(property string) []*Node { 498 net.lock.RLock() 499 defer net.lock.RUnlock() 500 501 return net.getNodesByProperty(property) 502 } 503 504 func (net *Network) getNodesByProperty(property string) []*Node { 505 nodes := make([]*Node, 0, len(net.propertyMap[property])) 506 for _, nodeIndex := range net.propertyMap[property] { 507 nodes = append(nodes, net.Nodes[nodeIndex]) 508 } 509 510 return nodes 511 } 512 513 // GetNodeIDsByProperty returns existing node's enode IDs that have the given property string registered in the NodeConfig 514 func (net *Network) GetNodeIDsByProperty(property string) []enode.ID { 515 net.lock.RLock() 516 defer net.lock.RUnlock() 517 518 return net.getNodeIDsByProperty(property) 519 } 520 521 func (net *Network) getNodeIDsByProperty(property string) []enode.ID { 522 nodeIDs := make([]enode.ID, 0, len(net.propertyMap[property])) 523 for _, nodeIndex := range net.propertyMap[property] { 524 node := net.Nodes[nodeIndex] 525 nodeIDs = append(nodeIDs, node.ID()) 526 } 527 528 return nodeIDs 529 } 530 531 // GetRandomUpNode returns a random node on the network, which is running. 532 func (net *Network) GetRandomUpNode(excludeIDs ...enode.ID) *Node { 533 net.lock.RLock() 534 defer net.lock.RUnlock() 535 return net.getRandomUpNode(excludeIDs...) 536 } 537 538 // GetRandomUpNode returns a random node on the network, which is running. 539 func (net *Network) getRandomUpNode(excludeIDs ...enode.ID) *Node { 540 return net.getRandomNode(net.getUpNodeIDs(), excludeIDs) 541 } 542 543 func (net *Network) getUpNodeIDs() (ids []enode.ID) { 544 for _, node := range net.Nodes { 545 if node.Up() { 546 ids = append(ids, node.ID()) 547 } 548 } 549 return ids 550 } 551 552 // GetRandomDownNode returns a random node on the network, which is stopped. 553 func (net *Network) GetRandomDownNode(excludeIDs ...enode.ID) *Node { 554 net.lock.RLock() 555 defer net.lock.RUnlock() 556 return net.getRandomNode(net.getDownNodeIDs(), excludeIDs) 557 } 558 559 func (net *Network) getDownNodeIDs() (ids []enode.ID) { 560 for _, node := range net.Nodes { 561 if !node.Up() { 562 ids = append(ids, node.ID()) 563 } 564 } 565 return ids 566 } 567 568 // GetRandomNode returns a random node on the network, regardless of whether it is running or not 569 func (net *Network) GetRandomNode(excludeIDs ...enode.ID) *Node { 570 net.lock.RLock() 571 defer net.lock.RUnlock() 572 return net.getRandomNode(net.getNodeIDs(nil), excludeIDs) // no need to exclude twice 573 } 574 575 func (net *Network) getRandomNode(ids []enode.ID, excludeIDs []enode.ID) *Node { 576 filtered := filterIDs(ids, excludeIDs) 577 578 l := len(filtered) 579 if l == 0 { 580 return nil 581 } 582 return net.getNode(filtered[rand.Intn(l)]) 583 } 584 585 func filterIDs(ids []enode.ID, excludeIDs []enode.ID) []enode.ID { 586 exclude := make(map[enode.ID]bool) 587 for _, id := range excludeIDs { 588 exclude[id] = true 589 } 590 var filtered []enode.ID 591 for _, id := range ids { 592 if _, found := exclude[id]; !found { 593 filtered = append(filtered, id) 594 } 595 } 596 return filtered 597 } 598 599 // GetConn returns the connection which exists between "one" and "other" 600 // regardless of which node initiated the connection 601 func (net *Network) GetConn(oneID, otherID enode.ID) *Conn { 602 net.lock.RLock() 603 defer net.lock.RUnlock() 604 return net.getConn(oneID, otherID) 605 } 606 607 // GetOrCreateConn is like GetConn but creates the connection if it doesn't 608 // already exist 609 func (net *Network) GetOrCreateConn(oneID, otherID enode.ID) (*Conn, error) { 610 net.lock.Lock() 611 defer net.lock.Unlock() 612 return net.getOrCreateConn(oneID, otherID) 613 } 614 615 func (net *Network) getOrCreateConn(oneID, otherID enode.ID) (*Conn, error) { 616 if conn := net.getConn(oneID, otherID); conn != nil { 617 return conn, nil 618 } 619 620 one := net.getNode(oneID) 621 if one == nil { 622 return nil, fmt.Errorf("node %v does not exist", oneID) 623 } 624 other := net.getNode(otherID) 625 if other == nil { 626 return nil, fmt.Errorf("node %v does not exist", otherID) 627 } 628 conn := &Conn{ 629 One: oneID, 630 Other: otherID, 631 one: one, 632 other: other, 633 } 634 label := ConnLabel(oneID, otherID) 635 net.connMap[label] = len(net.Conns) 636 net.Conns = append(net.Conns, conn) 637 return conn, nil 638 } 639 640 func (net *Network) getConn(oneID, otherID enode.ID) *Conn { 641 label := ConnLabel(oneID, otherID) 642 i, found := net.connMap[label] 643 if !found { 644 return nil 645 } 646 return net.Conns[i] 647 } 648 649 // InitConn retrieves the connection model for the connection between 650 // peers 'oneID' and 'otherID', or creates a new one if it does not exist 651 // the order of nodes does not matter, i.e., Conn(i,j) == Conn(j, i) 652 // it checks if the connection is already up, and if the nodes are running 653 // NOTE: 654 // it also checks whether there has been recent attempt to connect the peers 655 // this is cheating as the simulation is used as an oracle and know about 656 // remote peers attempt to connect to a node which will then not initiate the connection 657 func (net *Network) InitConn(oneID, otherID enode.ID) (*Conn, error) { 658 net.lock.Lock() 659 defer net.lock.Unlock() 660 return net.initConn(oneID, otherID) 661 } 662 663 func (net *Network) initConn(oneID, otherID enode.ID) (*Conn, error) { 664 if oneID == otherID { 665 return nil, fmt.Errorf("refusing to connect to self %v", oneID) 666 } 667 conn, err := net.getOrCreateConn(oneID, otherID) 668 if err != nil { 669 return nil, err 670 } 671 if conn.Up { 672 return nil, fmt.Errorf("%v and %v already connected", oneID, otherID) 673 } 674 if time.Since(conn.initiated) < DialBanTimeout { 675 return nil, fmt.Errorf("connection between %v and %v recently attempted", oneID, otherID) 676 } 677 678 err = conn.nodesUp() 679 if err != nil { 680 log.Trace("Nodes not up", "err", err) 681 return nil, fmt.Errorf("nodes not up: %v", err) 682 } 683 log.Debug("Connection initiated", "id", oneID, "other", otherID) 684 conn.initiated = time.Now() 685 return conn, nil 686 } 687 688 // Shutdown stops all nodes in the network and closes the quit channel 689 func (net *Network) Shutdown() { 690 for _, node := range net.Nodes { 691 log.Debug("Stopping node", "id", node.ID()) 692 if err := node.Stop(); err != nil { 693 log.Warn("Can't stop node", "id", node.ID(), "err", err) 694 } 695 } 696 close(net.quitc) 697 } 698 699 // Reset resets all network properties: 700 // empties the nodes and the connection list 701 func (net *Network) Reset() { 702 net.lock.Lock() 703 defer net.lock.Unlock() 704 705 //re-initialize the maps 706 net.connMap = make(map[string]int) 707 net.nodeMap = make(map[enode.ID]int) 708 net.propertyMap = make(map[string][]int) 709 710 net.Nodes = nil 711 net.Conns = nil 712 } 713 714 // Node is a wrapper around adapters.Node which is used to track the status 715 // of a node in the network 716 type Node struct { 717 adapters.Node `json:"-"` 718 719 // Config if the config used to created the node 720 Config *adapters.NodeConfig `json:"config"` 721 722 // up tracks whether or not the node is running 723 up bool 724 upMu *sync.RWMutex 725 } 726 727 func newNode(an adapters.Node, ac *adapters.NodeConfig, up bool) *Node { 728 return &Node{Node: an, Config: ac, up: up, upMu: new(sync.RWMutex)} 729 } 730 731 func (n *Node) copy() *Node { 732 configCpy := *n.Config 733 return newNode(n.Node, &configCpy, n.Up()) 734 } 735 736 // Up returns whether the node is currently up (online) 737 func (n *Node) Up() bool { 738 n.upMu.RLock() 739 defer n.upMu.RUnlock() 740 return n.up 741 } 742 743 // SetUp sets the up (online) status of the nodes with the given value 744 func (n *Node) SetUp(up bool) { 745 n.upMu.Lock() 746 defer n.upMu.Unlock() 747 n.up = up 748 } 749 750 // ID returns the ID of the node 751 func (n *Node) ID() enode.ID { 752 return n.Config.ID 753 } 754 755 // String returns a log-friendly string 756 func (n *Node) String() string { 757 return fmt.Sprintf("Node %v", n.ID().TerminalString()) 758 } 759 760 // NodeInfo returns information about the node 761 func (n *Node) NodeInfo() *p2p.NodeInfo { 762 // avoid a panic if the node is not started yet 763 if n.Node == nil { 764 return nil 765 } 766 info := n.Node.NodeInfo() 767 info.Name = n.Config.Name 768 return info 769 } 770 771 // MarshalJSON implements the json.Marshaler interface so that the encoded 772 // JSON includes the NodeInfo 773 func (n *Node) MarshalJSON() ([]byte, error) { 774 return json.Marshal(struct { 775 Info *p2p.NodeInfo `json:"info,omitempty"` 776 Config *adapters.NodeConfig `json:"config,omitempty"` 777 Up bool `json:"up"` 778 }{ 779 Info: n.NodeInfo(), 780 Config: n.Config, 781 Up: n.Up(), 782 }) 783 } 784 785 // UnmarshalJSON implements json.Unmarshaler interface so that we don't lose Node.up 786 // status. IMPORTANT: The implementation is incomplete; we lose p2p.NodeInfo. 787 func (n *Node) UnmarshalJSON(raw []byte) error { 788 // TODO: How should we turn back NodeInfo into n.Node? 789 // Ticket: https://github.com/ethersphere/go-ethereum/issues/1177 790 var node struct { 791 Config *adapters.NodeConfig `json:"config,omitempty"` 792 Up bool `json:"up"` 793 } 794 if err := json.Unmarshal(raw, &node); err != nil { 795 return err 796 } 797 *n = *newNode(nil, node.Config, node.Up) 798 return nil 799 } 800 801 // Conn represents a connection between two nodes in the network 802 type Conn struct { 803 // One is the node which initiated the connection 804 One enode.ID `json:"one"` 805 806 // Other is the node which the connection was made to 807 Other enode.ID `json:"other"` 808 809 // Up tracks whether or not the connection is active 810 Up bool `json:"up"` 811 // Registers when the connection was grabbed to dial 812 initiated time.Time 813 814 one *Node 815 other *Node 816 } 817 818 // nodesUp returns whether both nodes are currently up 819 func (c *Conn) nodesUp() error { 820 if !c.one.Up() { 821 return fmt.Errorf("one %v is not up", c.One) 822 } 823 if !c.other.Up() { 824 return fmt.Errorf("other %v is not up", c.Other) 825 } 826 return nil 827 } 828 829 // String returns a log-friendly string 830 func (c *Conn) String() string { 831 return fmt.Sprintf("Conn %v->%v", c.One.TerminalString(), c.Other.TerminalString()) 832 } 833 834 // Msg represents a p2p message sent between two nodes in the network 835 type Msg struct { 836 One enode.ID `json:"one"` 837 Other enode.ID `json:"other"` 838 Protocol string `json:"protocol"` 839 Code uint64 `json:"code"` 840 Received bool `json:"received"` 841 } 842 843 // String returns a log-friendly string 844 func (m *Msg) String() string { 845 return fmt.Sprintf("Msg(%d) %v->%v", m.Code, m.One.TerminalString(), m.Other.TerminalString()) 846 } 847 848 // ConnLabel generates a deterministic string which represents a connection 849 // between two nodes, used to compare if two connections are between the same 850 // nodes 851 func ConnLabel(source, target enode.ID) string { 852 var first, second enode.ID 853 if bytes.Compare(source.Bytes(), target.Bytes()) > 0 { 854 first = target 855 second = source 856 } else { 857 first = source 858 second = target 859 } 860 return fmt.Sprintf("%v-%v", first, second) 861 } 862 863 // Snapshot represents the state of a network at a single point in time and can 864 // be used to restore the state of a network 865 type Snapshot struct { 866 Nodes []NodeSnapshot `json:"nodes,omitempty"` 867 Conns []Conn `json:"conns,omitempty"` 868 } 869 870 // NodeSnapshot represents the state of a node in the network 871 type NodeSnapshot struct { 872 Node Node `json:"node,omitempty"` 873 874 // Snapshots is arbitrary data gathered from calling node.Snapshots() 875 Snapshots map[string][]byte `json:"snapshots,omitempty"` 876 } 877 878 // Snapshot creates a network snapshot 879 func (net *Network) Snapshot() (*Snapshot, error) { 880 return net.snapshot(nil, nil) 881 } 882 883 func (net *Network) SnapshotWithServices(addServices []string, removeServices []string) (*Snapshot, error) { 884 return net.snapshot(addServices, removeServices) 885 } 886 887 func (net *Network) snapshot(addServices []string, removeServices []string) (*Snapshot, error) { 888 net.lock.Lock() 889 defer net.lock.Unlock() 890 snap := &Snapshot{ 891 Nodes: make([]NodeSnapshot, len(net.Nodes)), 892 } 893 for i, node := range net.Nodes { 894 snap.Nodes[i] = NodeSnapshot{Node: *node.copy()} 895 if !node.Up() { 896 continue 897 } 898 snapshots, err := node.Snapshots() 899 if err != nil { 900 return nil, err 901 } 902 snap.Nodes[i].Snapshots = snapshots 903 for _, addSvc := range addServices { 904 haveSvc := false 905 for _, svc := range snap.Nodes[i].Node.Config.Lifecycles { 906 if svc == addSvc { 907 haveSvc = true 908 break 909 } 910 } 911 if !haveSvc { 912 snap.Nodes[i].Node.Config.Lifecycles = append(snap.Nodes[i].Node.Config.Lifecycles, addSvc) 913 } 914 } 915 if len(removeServices) > 0 { 916 var cleanedServices []string 917 for _, svc := range snap.Nodes[i].Node.Config.Lifecycles { 918 haveSvc := false 919 for _, rmSvc := range removeServices { 920 if rmSvc == svc { 921 haveSvc = true 922 break 923 } 924 } 925 if !haveSvc { 926 cleanedServices = append(cleanedServices, svc) 927 } 928 } 929 snap.Nodes[i].Node.Config.Lifecycles = cleanedServices 930 } 931 } 932 for _, conn := range net.Conns { 933 if conn.Up { 934 snap.Conns = append(snap.Conns, *conn) 935 } 936 } 937 return snap, nil 938 } 939 940 // longrunning tests may need a longer timeout 941 var snapshotLoadTimeout = 900 * time.Second 942 943 // Load loads a network snapshot 944 func (net *Network) Load(snap *Snapshot) error { 945 // Start nodes. 946 for _, n := range snap.Nodes { 947 if _, err := net.NewNodeWithConfig(n.Node.Config); err != nil { 948 return err 949 } 950 if !n.Node.Up() { 951 continue 952 } 953 if err := net.startWithSnapshots(n.Node.Config.ID, n.Snapshots); err != nil { 954 return err 955 } 956 } 957 958 // Prepare connection events counter. 959 allConnected := make(chan struct{}) // closed when all connections are established 960 done := make(chan struct{}) // ensures that the event loop goroutine is terminated 961 defer close(done) 962 963 // Subscribe to event channel. 964 // It needs to be done outside of the event loop goroutine (created below) 965 // to ensure that the event channel is blocking before connect calls are made. 966 events := make(chan *Event) 967 sub := net.Events().Subscribe(events) 968 defer sub.Unsubscribe() 969 970 go func() { 971 // Expected number of connections. 972 total := len(snap.Conns) 973 // Set of all established connections from the snapshot, not other connections. 974 // Key array element 0 is the connection One field value, and element 1 connection Other field. 975 connections := make(map[[2]enode.ID]struct{}, total) 976 977 for { 978 select { 979 case e := <-events: 980 // Ignore control events as they do not represent 981 // connect or disconnect (Up) state change. 982 if e.Control { 983 continue 984 } 985 // Detect only connection events. 986 if e.Type != EventTypeConn { 987 continue 988 } 989 connection := [2]enode.ID{e.Conn.One, e.Conn.Other} 990 // Nodes are still not connected or have been disconnected. 991 if !e.Conn.Up { 992 // Delete the connection from the set of established connections. 993 // This will prevent false positive in case disconnections happen. 994 delete(connections, connection) 995 log.Warn("load snapshot: unexpected disconnection", "one", e.Conn.One, "other", e.Conn.Other) 996 continue 997 } 998 // Check that the connection is from the snapshot. 999 for _, conn := range snap.Conns { 1000 if conn.One == e.Conn.One && conn.Other == e.Conn.Other { 1001 // Add the connection to the set of established connections. 1002 connections[connection] = struct{}{} 1003 if len(connections) == total { 1004 // Signal that all nodes are connected. 1005 close(allConnected) 1006 return 1007 } 1008 1009 break 1010 } 1011 } 1012 case <-done: 1013 // Load function returned, terminate this goroutine. 1014 return 1015 } 1016 } 1017 }() 1018 1019 // Start connecting. 1020 for _, conn := range snap.Conns { 1021 if !net.GetNode(conn.One).Up() || !net.GetNode(conn.Other).Up() { 1022 //in this case, at least one of the nodes of a connection is not up, 1023 //so it would result in the snapshot `Load` to fail 1024 continue 1025 } 1026 if err := net.Connect(conn.One, conn.Other); err != nil { 1027 return err 1028 } 1029 } 1030 1031 select { 1032 // Wait until all connections from the snapshot are established. 1033 case <-allConnected: 1034 // Make sure that we do not wait forever. 1035 case <-time.After(snapshotLoadTimeout): 1036 return errors.New("snapshot connections not established") 1037 } 1038 return nil 1039 } 1040 1041 // Subscribe reads control events from a channel and executes them 1042 func (net *Network) Subscribe(events chan *Event) { 1043 for { 1044 select { 1045 case event, ok := <-events: 1046 if !ok { 1047 return 1048 } 1049 if event.Control { 1050 net.executeControlEvent(event) 1051 } 1052 case <-net.quitc: 1053 return 1054 } 1055 } 1056 } 1057 1058 func (net *Network) executeControlEvent(event *Event) { 1059 log.Trace("Executing control event", "type", event.Type, "event", event) 1060 switch event.Type { 1061 case EventTypeNode: 1062 if err := net.executeNodeEvent(event); err != nil { 1063 log.Error("Error executing node event", "event", event, "err", err) 1064 } 1065 case EventTypeConn: 1066 if err := net.executeConnEvent(event); err != nil { 1067 log.Error("Error executing conn event", "event", event, "err", err) 1068 } 1069 case EventTypeMsg: 1070 log.Warn("Ignoring control msg event") 1071 } 1072 } 1073 1074 func (net *Network) executeNodeEvent(e *Event) error { 1075 if !e.Node.Up() { 1076 return net.Stop(e.Node.ID()) 1077 } 1078 1079 if _, err := net.NewNodeWithConfig(e.Node.Config); err != nil { 1080 return err 1081 } 1082 return net.Start(e.Node.ID()) 1083 } 1084 1085 func (net *Network) executeConnEvent(e *Event) error { 1086 if e.Conn.Up { 1087 return net.Connect(e.Conn.One, e.Conn.Other) 1088 } 1089 return net.Disconnect(e.Conn.One, e.Conn.Other) 1090 }