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