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