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