github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/p2p/simulations/network.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 19:16:42</date>
    10  //</624450107105873920>
    11  
    12  
    13  package simulations
    14  
    15  import (
    16  	"bytes"
    17  	"context"
    18  	"encoding/json"
    19  	"errors"
    20  	"fmt"
    21  	"math/rand"
    22  	"sync"
    23  	"time"
    24  
    25  	"github.com/ethereum/go-ethereum/event"
    26  	"github.com/ethereum/go-ethereum/log"
    27  	"github.com/ethereum/go-ethereum/p2p"
    28  	"github.com/ethereum/go-ethereum/p2p/enode"
    29  	"github.com/ethereum/go-ethereum/p2p/simulations/adapters"
    30  )
    31  
    32  var DialBanTimeout = 200 * time.Millisecond
    33  
    34  //networkconfig定义用于启动网络的配置选项
    35  type NetworkConfig struct {
    36  	ID             string `json:"id"`
    37  	DefaultService string `json:"default_service,omitempty"`
    38  }
    39  
    40  //网络模型一个P2P仿真网络,它由一组
    41  //模拟节点及其之间存在的连接。
    42  //
    43  //网络有一个单独的节点适配器,它实际上负责
    44  //启动节点并将它们连接在一起。
    45  //
    46  //当节点启动和停止时,网络会发出事件
    47  //连接和断开连接,以及在节点之间发送消息时。
    48  type Network struct {
    49  	NetworkConfig
    50  
    51  	Nodes   []*Node `json:"nodes"`
    52  	nodeMap map[enode.ID]int
    53  
    54  	Conns   []*Conn `json:"conns"`
    55  	connMap map[string]int
    56  
    57  	nodeAdapter adapters.NodeAdapter
    58  	events      event.Feed
    59  	lock        sync.RWMutex
    60  	quitc       chan struct{}
    61  }
    62  
    63  //newnetwork返回使用给定nodeadapter和networkconfig的网络
    64  func NewNetwork(nodeAdapter adapters.NodeAdapter, conf *NetworkConfig) *Network {
    65  	return &Network{
    66  		NetworkConfig: *conf,
    67  		nodeAdapter:   nodeAdapter,
    68  		nodeMap:       make(map[enode.ID]int),
    69  		connMap:       make(map[string]int),
    70  		quitc:         make(chan struct{}),
    71  	}
    72  }
    73  
    74  //事件返回网络的输出事件源。
    75  func (net *Network) Events() *event.Feed {
    76  	return &net.events
    77  }
    78  
    79  //new node with config使用给定的配置向网络添加新节点,
    80  //如果已存在具有相同ID或名称的节点,则返回错误
    81  func (net *Network) NewNodeWithConfig(conf *adapters.NodeConfig) (*Node, error) {
    82  	net.lock.Lock()
    83  	defer net.lock.Unlock()
    84  
    85  	if conf.Reachable == nil {
    86  		conf.Reachable = func(otherID enode.ID) bool {
    87  			_, err := net.InitConn(conf.ID, otherID)
    88  			if err != nil && bytes.Compare(conf.ID.Bytes(), otherID.Bytes()) < 0 {
    89  				return false
    90  			}
    91  			return true
    92  		}
    93  	}
    94  
    95  //检查节点是否已存在
    96  	if node := net.getNode(conf.ID); node != nil {
    97  		return nil, fmt.Errorf("node with ID %q already exists", conf.ID)
    98  	}
    99  	if node := net.getNodeByName(conf.Name); node != nil {
   100  		return nil, fmt.Errorf("node with name %q already exists", conf.Name)
   101  	}
   102  
   103  //如果未配置任何服务,请使用默认服务
   104  	if len(conf.Services) == 0 {
   105  		conf.Services = []string{net.DefaultService}
   106  	}
   107  
   108  //使用nodeadapter创建节点
   109  	adapterNode, err := net.nodeAdapter.NewNode(conf)
   110  	if err != nil {
   111  		return nil, err
   112  	}
   113  	node := &Node{
   114  		Node:   adapterNode,
   115  		Config: conf,
   116  	}
   117  	log.Trace("Node created", "id", conf.ID)
   118  	net.nodeMap[conf.ID] = len(net.Nodes)
   119  	net.Nodes = append(net.Nodes, node)
   120  
   121  //发出“控制”事件
   122  	net.events.Send(ControlEvent(node))
   123  
   124  	return node, nil
   125  }
   126  
   127  //config返回网络配置
   128  func (net *Network) Config() *NetworkConfig {
   129  	return &net.NetworkConfig
   130  }
   131  
   132  //StartAll启动网络中的所有节点
   133  func (net *Network) StartAll() error {
   134  	for _, node := range net.Nodes {
   135  		if node.Up {
   136  			continue
   137  		}
   138  		if err := net.Start(node.ID()); err != nil {
   139  			return err
   140  		}
   141  	}
   142  	return nil
   143  }
   144  
   145  //stopall停止网络中的所有节点
   146  func (net *Network) StopAll() error {
   147  	for _, node := range net.Nodes {
   148  		if !node.Up {
   149  			continue
   150  		}
   151  		if err := net.Stop(node.ID()); err != nil {
   152  			return err
   153  		}
   154  	}
   155  	return nil
   156  }
   157  
   158  //Start用给定的ID启动节点
   159  func (net *Network) Start(id enode.ID) error {
   160  	return net.startWithSnapshots(id, nil)
   161  }
   162  
   163  //StartWithSnapshots使用给定的ID启动节点
   164  //快照
   165  func (net *Network) startWithSnapshots(id enode.ID, snapshots map[string][]byte) error {
   166  	net.lock.Lock()
   167  	defer net.lock.Unlock()
   168  
   169  	node := net.getNode(id)
   170  	if node == nil {
   171  		return fmt.Errorf("node %v does not exist", id)
   172  	}
   173  	if node.Up {
   174  		return fmt.Errorf("node %v already up", id)
   175  	}
   176  	log.Trace("Starting node", "id", id, "adapter", net.nodeAdapter.Name())
   177  	if err := node.Start(snapshots); err != nil {
   178  		log.Warn("Node startup failed", "id", id, "err", err)
   179  		return err
   180  	}
   181  	node.Up = true
   182  	log.Info("Started node", "id", id)
   183  
   184  	net.events.Send(NewEvent(node))
   185  
   186  //订阅对等事件
   187  	client, err := node.Client()
   188  	if err != nil {
   189  		return fmt.Errorf("error getting rpc client  for node %v: %s", id, err)
   190  	}
   191  	events := make(chan *p2p.PeerEvent)
   192  	sub, err := client.Subscribe(context.Background(), "admin", events, "peerEvents")
   193  	if err != nil {
   194  		return fmt.Errorf("error getting peer events for node %v: %s", id, err)
   195  	}
   196  	go net.watchPeerEvents(id, events, sub)
   197  	return nil
   198  }
   199  
   200  //WatchPeerEvents从给定通道读取对等事件并发出
   201  //相应的网络事件
   202  func (net *Network) watchPeerEvents(id enode.ID, events chan *p2p.PeerEvent, sub event.Subscription) {
   203  	defer func() {
   204  		sub.Unsubscribe()
   205  
   206  //假设节点现在已关闭
   207  		net.lock.Lock()
   208  		defer net.lock.Unlock()
   209  		node := net.getNode(id)
   210  		if node == nil {
   211  			return
   212  		}
   213  		node.Up = false
   214  		net.events.Send(NewEvent(node))
   215  	}()
   216  	for {
   217  		select {
   218  		case event, ok := <-events:
   219  			if !ok {
   220  				return
   221  			}
   222  			peer := event.Peer
   223  			switch event.Type {
   224  
   225  			case p2p.PeerEventTypeAdd:
   226  				net.DidConnect(id, peer)
   227  
   228  			case p2p.PeerEventTypeDrop:
   229  				net.DidDisconnect(id, peer)
   230  
   231  			case p2p.PeerEventTypeMsgSend:
   232  				net.DidSend(id, peer, event.Protocol, *event.MsgCode)
   233  
   234  			case p2p.PeerEventTypeMsgRecv:
   235  				net.DidReceive(peer, id, event.Protocol, *event.MsgCode)
   236  
   237  			}
   238  
   239  		case err := <-sub.Err():
   240  			if err != nil {
   241  				log.Error("Error in peer event subscription", "id", id, "err", err)
   242  			}
   243  			return
   244  		}
   245  	}
   246  }
   247  
   248  //stop停止具有给定ID的节点
   249  func (net *Network) Stop(id enode.ID) error {
   250  	net.lock.Lock()
   251  	node := net.getNode(id)
   252  	if node == nil {
   253  		return fmt.Errorf("node %v does not exist", id)
   254  	}
   255  	if !node.Up {
   256  		return fmt.Errorf("node %v already down", id)
   257  	}
   258  	node.Up = false
   259  	net.lock.Unlock()
   260  
   261  	err := node.Stop()
   262  	if err != nil {
   263  		net.lock.Lock()
   264  		node.Up = true
   265  		net.lock.Unlock()
   266  		return err
   267  	}
   268  	log.Info("Stopped node", "id", id, "err", err)
   269  	net.events.Send(ControlEvent(node))
   270  	return nil
   271  }
   272  
   273  //connect通过调用“admin_addpeer”rpc将两个节点连接在一起
   274  //方法,以便它连接到“另一个”节点
   275  func (net *Network) Connect(oneID, otherID enode.ID) error {
   276  	log.Debug("Connecting nodes with addPeer", "id", oneID, "other", otherID)
   277  	conn, err := net.InitConn(oneID, otherID)
   278  	if err != nil {
   279  		return err
   280  	}
   281  	client, err := conn.one.Client()
   282  	if err != nil {
   283  		return err
   284  	}
   285  	net.events.Send(ControlEvent(conn))
   286  	return client.Call(nil, "admin_addPeer", string(conn.other.Addr()))
   287  }
   288  
   289  //断开连接通过调用“admin-removepeer”rpc断开两个节点的连接
   290  //方法,以便它与“另一个”节点断开连接
   291  func (net *Network) Disconnect(oneID, otherID enode.ID) error {
   292  	conn := net.GetConn(oneID, otherID)
   293  	if conn == nil {
   294  		return fmt.Errorf("connection between %v and %v does not exist", oneID, otherID)
   295  	}
   296  	if !conn.Up {
   297  		return fmt.Errorf("%v and %v already disconnected", oneID, otherID)
   298  	}
   299  	client, err := conn.one.Client()
   300  	if err != nil {
   301  		return err
   302  	}
   303  	net.events.Send(ControlEvent(conn))
   304  	return client.Call(nil, "admin_removePeer", string(conn.other.Addr()))
   305  }
   306  
   307  //didconnect跟踪“一个”节点连接到“另一个”节点的事实
   308  func (net *Network) DidConnect(one, other enode.ID) error {
   309  	net.lock.Lock()
   310  	defer net.lock.Unlock()
   311  	conn, err := net.getOrCreateConn(one, other)
   312  	if err != nil {
   313  		return fmt.Errorf("connection between %v and %v does not exist", one, other)
   314  	}
   315  	if conn.Up {
   316  		return fmt.Errorf("%v and %v already connected", one, other)
   317  	}
   318  	conn.Up = true
   319  	net.events.Send(NewEvent(conn))
   320  	return nil
   321  }
   322  
   323  //didisconnect跟踪“one”节点与
   324  //“其他”节点
   325  func (net *Network) DidDisconnect(one, other enode.ID) error {
   326  	net.lock.Lock()
   327  	defer net.lock.Unlock()
   328  	conn := net.getConn(one, other)
   329  	if conn == nil {
   330  		return fmt.Errorf("connection between %v and %v does not exist", one, other)
   331  	}
   332  	if !conn.Up {
   333  		return fmt.Errorf("%v and %v already disconnected", one, other)
   334  	}
   335  	conn.Up = false
   336  	conn.initiated = time.Now().Add(-DialBanTimeout)
   337  	net.events.Send(NewEvent(conn))
   338  	return nil
   339  }
   340  
   341  //didsend跟踪“sender”向“receiver”发送消息的事实
   342  func (net *Network) DidSend(sender, receiver enode.ID, proto string, code uint64) error {
   343  	msg := &Msg{
   344  		One:      sender,
   345  		Other:    receiver,
   346  		Protocol: proto,
   347  		Code:     code,
   348  		Received: false,
   349  	}
   350  	net.events.Send(NewEvent(msg))
   351  	return nil
   352  }
   353  
   354  //DidReceive跟踪“Receiver”从“Sender”收到消息的事实
   355  func (net *Network) DidReceive(sender, receiver enode.ID, proto string, code uint64) error {
   356  	msg := &Msg{
   357  		One:      sender,
   358  		Other:    receiver,
   359  		Protocol: proto,
   360  		Code:     code,
   361  		Received: true,
   362  	}
   363  	net.events.Send(NewEvent(msg))
   364  	return nil
   365  }
   366  
   367  //getnode获取具有给定ID的节点,如果该节点没有,则返回nil
   368  //存在
   369  func (net *Network) GetNode(id enode.ID) *Node {
   370  	net.lock.RLock()
   371  	defer net.lock.RUnlock()
   372  	return net.getNode(id)
   373  }
   374  
   375  //getnode获取具有给定名称的节点,如果该节点执行此操作,则返回nil
   376  //不存在
   377  func (net *Network) GetNodeByName(name string) *Node {
   378  	net.lock.RLock()
   379  	defer net.lock.RUnlock()
   380  	return net.getNodeByName(name)
   381  }
   382  
   383  func (net *Network) getNodeByName(name string) *Node {
   384  	for _, node := range net.Nodes {
   385  		if node.Config.Name == name {
   386  			return node
   387  		}
   388  	}
   389  	return nil
   390  }
   391  
   392  //GetNodes返回现有节点
   393  func (net *Network) GetNodes() (nodes []*Node) {
   394  	net.lock.RLock()
   395  	defer net.lock.RUnlock()
   396  
   397  	nodes = append(nodes, net.Nodes...)
   398  	return nodes
   399  }
   400  
   401  func (net *Network) getNode(id enode.ID) *Node {
   402  	i, found := net.nodeMap[id]
   403  	if !found {
   404  		return nil
   405  	}
   406  	return net.Nodes[i]
   407  }
   408  
   409  //getrandomupnode返回网络上正在运行的随机节点。
   410  func (net *Network) GetRandomUpNode(excludeIDs ...enode.ID) *Node {
   411  	net.lock.RLock()
   412  	defer net.lock.RUnlock()
   413  	return net.getRandomNode(net.getUpNodeIDs(), excludeIDs)
   414  }
   415  
   416  func (net *Network) getUpNodeIDs() (ids []enode.ID) {
   417  	for _, node := range net.Nodes {
   418  		if node.Up {
   419  			ids = append(ids, node.ID())
   420  		}
   421  	}
   422  	return ids
   423  }
   424  
   425  //GetRandomDownNode返回网络上的随机节点,该节点已停止。
   426  func (net *Network) GetRandomDownNode(excludeIDs ...enode.ID) *Node {
   427  	net.lock.RLock()
   428  	defer net.lock.RUnlock()
   429  	return net.getRandomNode(net.getDownNodeIDs(), excludeIDs)
   430  }
   431  
   432  func (net *Network) getDownNodeIDs() (ids []enode.ID) {
   433  	for _, node := range net.GetNodes() {
   434  		if !node.Up {
   435  			ids = append(ids, node.ID())
   436  		}
   437  	}
   438  	return ids
   439  }
   440  
   441  func (net *Network) getRandomNode(ids []enode.ID, excludeIDs []enode.ID) *Node {
   442  	filtered := filterIDs(ids, excludeIDs)
   443  
   444  	l := len(filtered)
   445  	if l == 0 {
   446  		return nil
   447  	}
   448  	return net.GetNode(filtered[rand.Intn(l)])
   449  }
   450  
   451  func filterIDs(ids []enode.ID, excludeIDs []enode.ID) []enode.ID {
   452  	exclude := make(map[enode.ID]bool)
   453  	for _, id := range excludeIDs {
   454  		exclude[id] = true
   455  	}
   456  	var filtered []enode.ID
   457  	for _, id := range ids {
   458  		if _, found := exclude[id]; !found {
   459  			filtered = append(filtered, id)
   460  		}
   461  	}
   462  	return filtered
   463  }
   464  
   465  //getconn返回“一”和“另一”之间存在的连接
   466  //无论哪个节点启动了连接
   467  func (net *Network) GetConn(oneID, otherID enode.ID) *Conn {
   468  	net.lock.RLock()
   469  	defer net.lock.RUnlock()
   470  	return net.getConn(oneID, otherID)
   471  }
   472  
   473  //getorCreateConn与getconn类似,但如果不相同,则创建连接
   474  //已经存在
   475  func (net *Network) GetOrCreateConn(oneID, otherID enode.ID) (*Conn, error) {
   476  	net.lock.Lock()
   477  	defer net.lock.Unlock()
   478  	return net.getOrCreateConn(oneID, otherID)
   479  }
   480  
   481  func (net *Network) getOrCreateConn(oneID, otherID enode.ID) (*Conn, error) {
   482  	if conn := net.getConn(oneID, otherID); conn != nil {
   483  		return conn, nil
   484  	}
   485  
   486  	one := net.getNode(oneID)
   487  	if one == nil {
   488  		return nil, fmt.Errorf("node %v does not exist", oneID)
   489  	}
   490  	other := net.getNode(otherID)
   491  	if other == nil {
   492  		return nil, fmt.Errorf("node %v does not exist", otherID)
   493  	}
   494  	conn := &Conn{
   495  		One:   oneID,
   496  		Other: otherID,
   497  		one:   one,
   498  		other: other,
   499  	}
   500  	label := ConnLabel(oneID, otherID)
   501  	net.connMap[label] = len(net.Conns)
   502  	net.Conns = append(net.Conns, conn)
   503  	return conn, nil
   504  }
   505  
   506  func (net *Network) getConn(oneID, otherID enode.ID) *Conn {
   507  	label := ConnLabel(oneID, otherID)
   508  	i, found := net.connMap[label]
   509  	if !found {
   510  		return nil
   511  	}
   512  	return net.Conns[i]
   513  }
   514  
   515  //initconn(一个,另一个)检索
   516  //彼此对等,如果不存在则创建一个新的
   517  //节点顺序无关紧要,即conn(i,j)==conn(j,i)
   518  //它检查连接是否已经启动,以及节点是否正在运行
   519  //注:
   520  //它还检查最近是否有连接对等端的尝试
   521  //这是欺骗,因为模拟被用作甲骨文并知道
   522  //远程对等机尝试连接到一个节点,该节点随后将不会启动连接。
   523  func (net *Network) InitConn(oneID, otherID enode.ID) (*Conn, error) {
   524  	net.lock.Lock()
   525  	defer net.lock.Unlock()
   526  	if oneID == otherID {
   527  		return nil, fmt.Errorf("refusing to connect to self %v", oneID)
   528  	}
   529  	conn, err := net.getOrCreateConn(oneID, otherID)
   530  	if err != nil {
   531  		return nil, err
   532  	}
   533  	if conn.Up {
   534  		return nil, fmt.Errorf("%v and %v already connected", oneID, otherID)
   535  	}
   536  	if time.Since(conn.initiated) < DialBanTimeout {
   537  		return nil, fmt.Errorf("connection between %v and %v recently attempted", oneID, otherID)
   538  	}
   539  
   540  	err = conn.nodesUp()
   541  	if err != nil {
   542  		log.Trace("Nodes not up", "err", err)
   543  		return nil, fmt.Errorf("nodes not up: %v", err)
   544  	}
   545  	log.Debug("Connection initiated", "id", oneID, "other", otherID)
   546  	conn.initiated = time.Now()
   547  	return conn, nil
   548  }
   549  
   550  //shutdown停止网络中的所有节点并关闭退出通道
   551  func (net *Network) Shutdown() {
   552  	for _, node := range net.Nodes {
   553  		log.Debug("Stopping node", "id", node.ID())
   554  		if err := node.Stop(); err != nil {
   555  			log.Warn("Can't stop node", "id", node.ID(), "err", err)
   556  		}
   557  	}
   558  	close(net.quitc)
   559  }
   560  
   561  //重置重置所有网络属性:
   562  //清空节点和连接列表
   563  func (net *Network) Reset() {
   564  	net.lock.Lock()
   565  	defer net.lock.Unlock()
   566  
   567  //重新初始化映射
   568  	net.connMap = make(map[string]int)
   569  	net.nodeMap = make(map[enode.ID]int)
   570  
   571  	net.Nodes = nil
   572  	net.Conns = nil
   573  }
   574  
   575  //node是围绕adapters.node的包装器,用于跟踪状态
   576  //网络中节点的
   577  type Node struct {
   578  	adapters.Node `json:"-"`
   579  
   580  //如果用于创建节点的配置
   581  	Config *adapters.NodeConfig `json:"config"`
   582  
   583  //向上跟踪节点是否正在运行
   584  	Up bool `json:"up"`
   585  }
   586  
   587  //ID返回节点的ID
   588  func (n *Node) ID() enode.ID {
   589  	return n.Config.ID
   590  }
   591  
   592  //字符串返回日志友好的字符串
   593  func (n *Node) String() string {
   594  	return fmt.Sprintf("Node %v", n.ID().TerminalString())
   595  }
   596  
   597  //nodeinfo返回有关节点的信息
   598  func (n *Node) NodeInfo() *p2p.NodeInfo {
   599  //如果节点尚未启动,请避免出现恐慌。
   600  	if n.Node == nil {
   601  		return nil
   602  	}
   603  	info := n.Node.NodeInfo()
   604  	info.Name = n.Config.Name
   605  	return info
   606  }
   607  
   608  //marshaljson实现json.marshaler接口,以便
   609  //json包括nodeinfo
   610  func (n *Node) MarshalJSON() ([]byte, error) {
   611  	return json.Marshal(struct {
   612  		Info   *p2p.NodeInfo        `json:"info,omitempty"`
   613  		Config *adapters.NodeConfig `json:"config,omitempty"`
   614  		Up     bool                 `json:"up"`
   615  	}{
   616  		Info:   n.NodeInfo(),
   617  		Config: n.Config,
   618  		Up:     n.Up,
   619  	})
   620  }
   621  
   622  //conn表示网络中两个节点之间的连接
   623  type Conn struct {
   624  //一个是启动连接的节点
   625  	One enode.ID `json:"one"`
   626  
   627  //另一个是连接到的节点
   628  	Other enode.ID `json:"other"`
   629  
   630  //向上跟踪连接是否处于活动状态
   631  	Up bool `json:"up"`
   632  //当连接被抓取拨号时注册
   633  	initiated time.Time
   634  
   635  	one   *Node
   636  	other *Node
   637  }
   638  
   639  //nodes up返回两个节点当前是否都已启动
   640  func (c *Conn) nodesUp() error {
   641  	if !c.one.Up {
   642  		return fmt.Errorf("one %v is not up", c.One)
   643  	}
   644  	if !c.other.Up {
   645  		return fmt.Errorf("other %v is not up", c.Other)
   646  	}
   647  	return nil
   648  }
   649  
   650  //字符串返回日志友好的字符串
   651  func (c *Conn) String() string {
   652  	return fmt.Sprintf("Conn %v->%v", c.One.TerminalString(), c.Other.TerminalString())
   653  }
   654  
   655  //msg表示网络中两个节点之间发送的P2P消息
   656  type Msg struct {
   657  	One      enode.ID `json:"one"`
   658  	Other    enode.ID `json:"other"`
   659  	Protocol string   `json:"protocol"`
   660  	Code     uint64   `json:"code"`
   661  	Received bool     `json:"received"`
   662  }
   663  
   664  //字符串返回日志友好的字符串
   665  func (m *Msg) String() string {
   666  	return fmt.Sprintf("Msg(%d) %v->%v", m.Code, m.One.TerminalString(), m.Other.TerminalString())
   667  }
   668  
   669  //connlabel生成表示连接的确定字符串
   670  //两个节点之间,用于比较两个连接是否相同
   671  //结点
   672  func ConnLabel(source, target enode.ID) string {
   673  	var first, second enode.ID
   674  	if bytes.Compare(source.Bytes(), target.Bytes()) > 0 {
   675  		first = target
   676  		second = source
   677  	} else {
   678  		first = source
   679  		second = target
   680  	}
   681  	return fmt.Sprintf("%v-%v", first, second)
   682  }
   683  
   684  //快照表示网络在单个时间点的状态,可以
   685  //用于恢复网络状态
   686  type Snapshot struct {
   687  	Nodes []NodeSnapshot `json:"nodes,omitempty"`
   688  	Conns []Conn         `json:"conns,omitempty"`
   689  }
   690  
   691  //nodesnapshot表示网络中节点的状态
   692  type NodeSnapshot struct {
   693  	Node Node `json:"node,omitempty"`
   694  
   695  //快照是从调用节点收集的任意数据。快照()
   696  	Snapshots map[string][]byte `json:"snapshots,omitempty"`
   697  }
   698  
   699  //快照创建网络快照
   700  func (net *Network) Snapshot() (*Snapshot, error) {
   701  	return net.snapshot(nil, nil)
   702  }
   703  
   704  func (net *Network) SnapshotWithServices(addServices []string, removeServices []string) (*Snapshot, error) {
   705  	return net.snapshot(addServices, removeServices)
   706  }
   707  
   708  func (net *Network) snapshot(addServices []string, removeServices []string) (*Snapshot, error) {
   709  	net.lock.Lock()
   710  	defer net.lock.Unlock()
   711  	snap := &Snapshot{
   712  		Nodes: make([]NodeSnapshot, len(net.Nodes)),
   713  	}
   714  	for i, node := range net.Nodes {
   715  		snap.Nodes[i] = NodeSnapshot{Node: *node}
   716  		if !node.Up {
   717  			continue
   718  		}
   719  		snapshots, err := node.Snapshots()
   720  		if err != nil {
   721  			return nil, err
   722  		}
   723  		snap.Nodes[i].Snapshots = snapshots
   724  		for _, addSvc := range addServices {
   725  			haveSvc := false
   726  			for _, svc := range snap.Nodes[i].Node.Config.Services {
   727  				if svc == addSvc {
   728  					haveSvc = true
   729  					break
   730  				}
   731  			}
   732  			if !haveSvc {
   733  				snap.Nodes[i].Node.Config.Services = append(snap.Nodes[i].Node.Config.Services, addSvc)
   734  			}
   735  		}
   736  		if len(removeServices) > 0 {
   737  			var cleanedServices []string
   738  			for _, svc := range snap.Nodes[i].Node.Config.Services {
   739  				haveSvc := false
   740  				for _, rmSvc := range removeServices {
   741  					if rmSvc == svc {
   742  						haveSvc = true
   743  						break
   744  					}
   745  				}
   746  				if !haveSvc {
   747  					cleanedServices = append(cleanedServices, svc)
   748  				}
   749  
   750  			}
   751  			snap.Nodes[i].Node.Config.Services = cleanedServices
   752  		}
   753  	}
   754  	for _, conn := range net.Conns {
   755  		if conn.Up {
   756  			snap.Conns = append(snap.Conns, *conn)
   757  		}
   758  	}
   759  	return snap, nil
   760  }
   761  
   762  var snapshotLoadTimeout = 120 * time.Second
   763  
   764  //加载加载网络快照
   765  func (net *Network) Load(snap *Snapshot) error {
   766  //启动节点。
   767  	for _, n := range snap.Nodes {
   768  		if _, err := net.NewNodeWithConfig(n.Node.Config); err != nil {
   769  			return err
   770  		}
   771  		if !n.Node.Up {
   772  			continue
   773  		}
   774  		if err := net.startWithSnapshots(n.Node.Config.ID, n.Snapshots); err != nil {
   775  			return err
   776  		}
   777  	}
   778  
   779  //准备连接事件计数器。
   780  allConnected := make(chan struct{}) //建立所有连接时关闭
   781  done := make(chan struct{})         //确保事件循环goroutine已终止
   782  	defer close(done)
   783  
   784  //订阅事件通道。
   785  //它需要在事件循环Goroutine之外完成(创建于下面)
   786  //以确保在进行连接调用之前事件通道被阻塞。
   787  	events := make(chan *Event)
   788  	sub := net.Events().Subscribe(events)
   789  	defer sub.Unsubscribe()
   790  
   791  	go func() {
   792  //预期的连接数。
   793  		total := len(snap.Conns)
   794  //从快照建立的所有连接的集合,而不是其他连接。
   795  //键数组元素0是连接一个字段值,元素1连接另一个字段。
   796  		connections := make(map[[2]enode.ID]struct{}, total)
   797  
   798  		for {
   799  			select {
   800  			case e := <-events:
   801  //忽略控件事件,因为它们不表示
   802  //连接或断开(向上)状态更改。
   803  				if e.Control {
   804  					continue
   805  				}
   806  //仅检测连接事件。
   807  				if e.Type != EventTypeConn {
   808  					continue
   809  				}
   810  				connection := [2]enode.ID{e.Conn.One, e.Conn.Other}
   811  //节点仍然未连接或已断开连接。
   812  				if !e.Conn.Up {
   813  //从已建立的连接集中删除连接。
   814  //这样可以防止断开时出现假阳性。
   815  					delete(connections, connection)
   816  					log.Warn("load snapshot: unexpected disconnection", "one", e.Conn.One, "other", e.Conn.Other)
   817  					continue
   818  				}
   819  //检查连接是否来自快照。
   820  				for _, conn := range snap.Conns {
   821  					if conn.One == e.Conn.One && conn.Other == e.Conn.Other {
   822  //将连接添加到已建立的连接集。
   823  						connections[connection] = struct{}{}
   824  						if len(connections) == total {
   825  //所有节点都已连接的信号。
   826  							close(allConnected)
   827  							return
   828  						}
   829  
   830  						break
   831  					}
   832  				}
   833  			case <-done:
   834  //加载函数返回,终止此goroutine。
   835  				return
   836  			}
   837  		}
   838  	}()
   839  
   840  //开始连接。
   841  	for _, conn := range snap.Conns {
   842  
   843  		if !net.GetNode(conn.One).Up || !net.GetNode(conn.Other).Up {
   844  //在这种情况下,连接的至少一个节点没有启动,
   845  //所以会导致快照“加载”失败
   846  			continue
   847  		}
   848  		if err := net.Connect(conn.One, conn.Other); err != nil {
   849  			return err
   850  		}
   851  	}
   852  
   853  	select {
   854  //等待快照的所有连接建立。
   855  	case <-allConnected:
   856  //确保我们不会永远等待。
   857  	case <-time.After(snapshotLoadTimeout):
   858  		return errors.New("snapshot connections not established")
   859  	}
   860  	return nil
   861  }
   862  
   863  //订阅从通道读取控制事件并执行它们
   864  func (net *Network) Subscribe(events chan *Event) {
   865  	for {
   866  		select {
   867  		case event, ok := <-events:
   868  			if !ok {
   869  				return
   870  			}
   871  			if event.Control {
   872  				net.executeControlEvent(event)
   873  			}
   874  		case <-net.quitc:
   875  			return
   876  		}
   877  	}
   878  }
   879  
   880  func (net *Network) executeControlEvent(event *Event) {
   881  	log.Trace("Executing control event", "type", event.Type, "event", event)
   882  	switch event.Type {
   883  	case EventTypeNode:
   884  		if err := net.executeNodeEvent(event); err != nil {
   885  			log.Error("Error executing node event", "event", event, "err", err)
   886  		}
   887  	case EventTypeConn:
   888  		if err := net.executeConnEvent(event); err != nil {
   889  			log.Error("Error executing conn event", "event", event, "err", err)
   890  		}
   891  	case EventTypeMsg:
   892  		log.Warn("Ignoring control msg event")
   893  	}
   894  }
   895  
   896  func (net *Network) executeNodeEvent(e *Event) error {
   897  	if !e.Node.Up {
   898  		return net.Stop(e.Node.ID())
   899  	}
   900  
   901  	if _, err := net.NewNodeWithConfig(e.Node.Config); err != nil {
   902  		return err
   903  	}
   904  	return net.Start(e.Node.ID())
   905  }
   906  
   907  func (net *Network) executeConnEvent(e *Event) error {
   908  	if e.Conn.Up {
   909  		return net.Connect(e.Conn.One, e.Conn.Other)
   910  	} else {
   911  		return net.Disconnect(e.Conn.One, e.Conn.Other)
   912  	}
   913  }
   914