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