github.com/aswedchain/aswed@v1.0.1/p2p/simulations/network.go (about)

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