github.com/xinfinOrg/xdposchain@v1.1.0/p2p/simulations/network.go (about)

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