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  }