github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/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 12:09:45</date>
    10  //</624342661658054656>
    11  
    12  
    13  package simulations
    14  
    15  import (
    16  	"bytes"
    17  	"context"
    18  	"encoding/json"
    19  	"fmt"
    20  	"sync"
    21  	"time"
    22  
    23  	"github.com/ethereum/go-ethereum/event"
    24  	"github.com/ethereum/go-ethereum/log"
    25  	"github.com/ethereum/go-ethereum/p2p"
    26  	"github.com/ethereum/go-ethereum/p2p/discover"
    27  	"github.com/ethereum/go-ethereum/p2p/simulations/adapters"
    28  )
    29  
    30  var DialBanTimeout = 200 * time.Millisecond
    31  
    32  //networkconfig定义用于启动网络的配置选项
    33  type NetworkConfig struct {
    34  	ID             string `json:"id"`
    35  	DefaultService string `json:"default_service,omitempty"`
    36  }
    37  
    38  //网络模型一个P2P仿真网络,它由一组
    39  //模拟节点及其之间存在的连接。
    40  //
    41  //网络有一个单独的节点适配器,它实际上负责
    42  //启动节点并将它们连接在一起。
    43  //
    44  //当节点启动和停止时,网络会发出事件
    45  //连接和断开连接,以及在节点之间发送消息时。
    46  type Network struct {
    47  	NetworkConfig
    48  
    49  	Nodes   []*Node `json:"nodes"`
    50  	nodeMap map[discover.NodeID]int
    51  
    52  	Conns   []*Conn `json:"conns"`
    53  	connMap map[string]int
    54  
    55  	nodeAdapter adapters.NodeAdapter
    56  	events      event.Feed
    57  	lock        sync.RWMutex
    58  	quitc       chan struct{}
    59  }
    60  
    61  //newnetwork返回使用给定nodeadapter和networkconfig的网络
    62  func NewNetwork(nodeAdapter adapters.NodeAdapter, conf *NetworkConfig) *Network {
    63  	return &Network{
    64  		NetworkConfig: *conf,
    65  		nodeAdapter:   nodeAdapter,
    66  		nodeMap:       make(map[discover.NodeID]int),
    67  		connMap:       make(map[string]int),
    68  		quitc:         make(chan struct{}),
    69  	}
    70  }
    71  
    72  //事件返回网络的输出事件源。
    73  func (net *Network) Events() *event.Feed {
    74  	return &net.events
    75  }
    76  
    77  //new node with config使用给定的配置向网络添加新节点,
    78  //如果已存在具有相同ID或名称的节点,则返回错误
    79  func (net *Network) NewNodeWithConfig(conf *adapters.NodeConfig) (*Node, error) {
    80  	net.lock.Lock()
    81  	defer net.lock.Unlock()
    82  
    83  	if conf.Reachable == nil {
    84  		conf.Reachable = func(otherID discover.NodeID) bool {
    85  			_, err := net.InitConn(conf.ID, otherID)
    86  			if err != nil && bytes.Compare(conf.ID.Bytes(), otherID.Bytes()) < 0 {
    87  				return false
    88  			}
    89  			return true
    90  		}
    91  	}
    92  
    93  //检查节点是否已存在
    94  	if node := net.getNode(conf.ID); node != nil {
    95  		return nil, fmt.Errorf("node with ID %q already exists", conf.ID)
    96  	}
    97  	if node := net.getNodeByName(conf.Name); node != nil {
    98  		return nil, fmt.Errorf("node with name %q already exists", conf.Name)
    99  	}
   100  
   101  //如果未配置任何服务,请使用默认服务
   102  	if len(conf.Services) == 0 {
   103  		conf.Services = []string{net.DefaultService}
   104  	}
   105  
   106  //使用nodeadapter创建节点
   107  	adapterNode, err := net.nodeAdapter.NewNode(conf)
   108  	if err != nil {
   109  		return nil, err
   110  	}
   111  	node := &Node{
   112  		Node:   adapterNode,
   113  		Config: conf,
   114  	}
   115  	log.Trace(fmt.Sprintf("node %v created", conf.ID))
   116  	net.nodeMap[conf.ID] = len(net.Nodes)
   117  	net.Nodes = append(net.Nodes, node)
   118  
   119  //发出“控制”事件
   120  	net.events.Send(ControlEvent(node))
   121  
   122  	return node, nil
   123  }
   124  
   125  //config返回网络配置
   126  func (net *Network) Config() *NetworkConfig {
   127  	return &net.NetworkConfig
   128  }
   129  
   130  //StartAll启动网络中的所有节点
   131  func (net *Network) StartAll() error {
   132  	for _, node := range net.Nodes {
   133  		if node.Up {
   134  			continue
   135  		}
   136  		if err := net.Start(node.ID()); err != nil {
   137  			return err
   138  		}
   139  	}
   140  	return nil
   141  }
   142  
   143  //stopall停止网络中的所有节点
   144  func (net *Network) StopAll() error {
   145  	for _, node := range net.Nodes {
   146  		if !node.Up {
   147  			continue
   148  		}
   149  		if err := net.Stop(node.ID()); err != nil {
   150  			return err
   151  		}
   152  	}
   153  	return nil
   154  }
   155  
   156  //Start用给定的ID启动节点
   157  func (net *Network) Start(id discover.NodeID) error {
   158  	return net.startWithSnapshots(id, nil)
   159  }
   160  
   161  //StartWithSnapshots使用给定的ID启动节点
   162  //快照
   163  func (net *Network) startWithSnapshots(id discover.NodeID, snapshots map[string][]byte) error {
   164  	net.lock.Lock()
   165  	defer net.lock.Unlock()
   166  	node := net.getNode(id)
   167  	if node == nil {
   168  		return fmt.Errorf("node %v does not exist", id)
   169  	}
   170  	if node.Up {
   171  		return fmt.Errorf("node %v already up", id)
   172  	}
   173  	log.Trace(fmt.Sprintf("starting node %v: %v using %v", id, node.Up, net.nodeAdapter.Name()))
   174  	if err := node.Start(snapshots); err != nil {
   175  		log.Warn(fmt.Sprintf("start up failed: %v", err))
   176  		return err
   177  	}
   178  	node.Up = true
   179  	log.Info(fmt.Sprintf("started node %v: %v", id, node.Up))
   180  
   181  	net.events.Send(NewEvent(node))
   182  
   183  //订阅对等事件
   184  	client, err := node.Client()
   185  	if err != nil {
   186  		return fmt.Errorf("error getting rpc client  for node %v: %s", id, err)
   187  	}
   188  	events := make(chan *p2p.PeerEvent)
   189  	sub, err := client.Subscribe(context.Background(), "admin", events, "peerEvents")
   190  	if err != nil {
   191  		return fmt.Errorf("error getting peer events for node %v: %s", id, err)
   192  	}
   193  	go net.watchPeerEvents(id, events, sub)
   194  	return nil
   195  }
   196  
   197  //WatchPeerEvents从给定通道读取对等事件并发出
   198  //相应的网络事件
   199  func (net *Network) watchPeerEvents(id discover.NodeID, events chan *p2p.PeerEvent, sub event.Subscription) {
   200  	defer func() {
   201  		sub.Unsubscribe()
   202  
   203  //假设节点现在已关闭
   204  		net.lock.Lock()
   205  		defer net.lock.Unlock()
   206  		node := net.getNode(id)
   207  		if node == nil {
   208  			log.Error("Can not find node for id", "id", id)
   209  			return
   210  		}
   211  		node.Up = false
   212  		net.events.Send(NewEvent(node))
   213  	}()
   214  	for {
   215  		select {
   216  		case event, ok := <-events:
   217  			if !ok {
   218  				return
   219  			}
   220  			peer := event.Peer
   221  			switch event.Type {
   222  
   223  			case p2p.PeerEventTypeAdd:
   224  				net.DidConnect(id, peer)
   225  
   226  			case p2p.PeerEventTypeDrop:
   227  				net.DidDisconnect(id, peer)
   228  
   229  			case p2p.PeerEventTypeMsgSend:
   230  				net.DidSend(id, peer, event.Protocol, *event.MsgCode)
   231  
   232  			case p2p.PeerEventTypeMsgRecv:
   233  				net.DidReceive(peer, id, event.Protocol, *event.MsgCode)
   234  
   235  			}
   236  
   237  		case err := <-sub.Err():
   238  			if err != nil {
   239  				log.Error(fmt.Sprintf("error getting peer events for node %v", id), "err", err)
   240  			}
   241  			return
   242  		}
   243  	}
   244  }
   245  
   246  //stop停止具有给定ID的节点
   247  func (net *Network) Stop(id discover.NodeID) error {
   248  	net.lock.Lock()
   249  	defer net.lock.Unlock()
   250  	node := net.getNode(id)
   251  	if node == nil {
   252  		return fmt.Errorf("node %v does not exist", id)
   253  	}
   254  	if !node.Up {
   255  		return fmt.Errorf("node %v already down", id)
   256  	}
   257  	if err := node.Stop(); err != nil {
   258  		return err
   259  	}
   260  	node.Up = false
   261  	log.Info(fmt.Sprintf("stop node %v: %v", id, node.Up))
   262  
   263  	net.events.Send(ControlEvent(node))
   264  	return nil
   265  }
   266  
   267  //connect通过调用“admin_addpeer”rpc将两个节点连接在一起
   268  //方法,以便它连接到“另一个”节点
   269  func (net *Network) Connect(oneID, otherID discover.NodeID) error {
   270  	log.Debug(fmt.Sprintf("connecting %s to %s", oneID, otherID))
   271  	conn, err := net.InitConn(oneID, otherID)
   272  	if err != nil {
   273  		return err
   274  	}
   275  	client, err := conn.one.Client()
   276  	if err != nil {
   277  		return err
   278  	}
   279  	net.events.Send(ControlEvent(conn))
   280  	return client.Call(nil, "admin_addPeer", string(conn.other.Addr()))
   281  }
   282  
   283  //断开连接通过调用“admin-removepeer”rpc断开两个节点的连接
   284  //方法,以便它与“另一个”节点断开连接
   285  func (net *Network) Disconnect(oneID, otherID discover.NodeID) error {
   286  	conn := net.GetConn(oneID, otherID)
   287  	if conn == nil {
   288  		return fmt.Errorf("connection between %v and %v does not exist", oneID, otherID)
   289  	}
   290  	if !conn.Up {
   291  		return fmt.Errorf("%v and %v already disconnected", oneID, otherID)
   292  	}
   293  	client, err := conn.one.Client()
   294  	if err != nil {
   295  		return err
   296  	}
   297  	net.events.Send(ControlEvent(conn))
   298  	return client.Call(nil, "admin_removePeer", string(conn.other.Addr()))
   299  }
   300  
   301  //didconnect跟踪“一个”节点连接到“另一个”节点的事实
   302  func (net *Network) DidConnect(one, other discover.NodeID) error {
   303  	net.lock.Lock()
   304  	defer net.lock.Unlock()
   305  	conn, err := net.getOrCreateConn(one, other)
   306  	if err != nil {
   307  		return fmt.Errorf("connection between %v and %v does not exist", one, other)
   308  	}
   309  	if conn.Up {
   310  		return fmt.Errorf("%v and %v already connected", one, other)
   311  	}
   312  	conn.Up = true
   313  	net.events.Send(NewEvent(conn))
   314  	return nil
   315  }
   316  
   317  //didisconnect跟踪“one”节点与
   318  //“其他”节点
   319  func (net *Network) DidDisconnect(one, other discover.NodeID) error {
   320  	net.lock.Lock()
   321  	defer net.lock.Unlock()
   322  	conn := net.getConn(one, other)
   323  	if conn == nil {
   324  		return fmt.Errorf("connection between %v and %v does not exist", one, other)
   325  	}
   326  	if !conn.Up {
   327  		return fmt.Errorf("%v and %v already disconnected", one, other)
   328  	}
   329  	conn.Up = false
   330  	conn.initiated = time.Now().Add(-DialBanTimeout)
   331  	net.events.Send(NewEvent(conn))
   332  	return nil
   333  }
   334  
   335  //didsend跟踪“sender”向“receiver”发送消息的事实
   336  func (net *Network) DidSend(sender, receiver discover.NodeID, proto string, code uint64) error {
   337  	msg := &Msg{
   338  		One:      sender,
   339  		Other:    receiver,
   340  		Protocol: proto,
   341  		Code:     code,
   342  		Received: false,
   343  	}
   344  	net.events.Send(NewEvent(msg))
   345  	return nil
   346  }
   347  
   348  //DidReceive跟踪“Receiver”从“Sender”收到消息的事实
   349  func (net *Network) DidReceive(sender, receiver discover.NodeID, proto string, code uint64) error {
   350  	msg := &Msg{
   351  		One:      sender,
   352  		Other:    receiver,
   353  		Protocol: proto,
   354  		Code:     code,
   355  		Received: true,
   356  	}
   357  	net.events.Send(NewEvent(msg))
   358  	return nil
   359  }
   360  
   361  //getnode获取具有给定ID的节点,如果该节点没有,则返回nil
   362  //存在
   363  func (net *Network) GetNode(id discover.NodeID) *Node {
   364  	net.lock.Lock()
   365  	defer net.lock.Unlock()
   366  	return net.getNode(id)
   367  }
   368  
   369  //getnode获取具有给定名称的节点,如果该节点执行此操作,则返回nil
   370  //不存在
   371  func (net *Network) GetNodeByName(name string) *Node {
   372  	net.lock.Lock()
   373  	defer net.lock.Unlock()
   374  	return net.getNodeByName(name)
   375  }
   376  
   377  //GetNodes返回现有节点
   378  func (net *Network) GetNodes() (nodes []*Node) {
   379  	net.lock.Lock()
   380  	defer net.lock.Unlock()
   381  
   382  	nodes = append(nodes, net.Nodes...)
   383  	return nodes
   384  }
   385  
   386  func (net *Network) getNode(id discover.NodeID) *Node {
   387  	i, found := net.nodeMap[id]
   388  	if !found {
   389  		return nil
   390  	}
   391  	return net.Nodes[i]
   392  }
   393  
   394  func (net *Network) getNodeByName(name string) *Node {
   395  	for _, node := range net.Nodes {
   396  		if node.Config.Name == name {
   397  			return node
   398  		}
   399  	}
   400  	return nil
   401  }
   402  
   403  //getconn返回“一”和“另一”之间存在的连接
   404  //无论哪个节点启动了连接
   405  func (net *Network) GetConn(oneID, otherID discover.NodeID) *Conn {
   406  	net.lock.Lock()
   407  	defer net.lock.Unlock()
   408  	return net.getConn(oneID, otherID)
   409  }
   410  
   411  //getorCreateConn与getconn类似,但如果不相同,则创建连接
   412  //已经存在
   413  func (net *Network) GetOrCreateConn(oneID, otherID discover.NodeID) (*Conn, error) {
   414  	net.lock.Lock()
   415  	defer net.lock.Unlock()
   416  	return net.getOrCreateConn(oneID, otherID)
   417  }
   418  
   419  func (net *Network) getOrCreateConn(oneID, otherID discover.NodeID) (*Conn, error) {
   420  	if conn := net.getConn(oneID, otherID); conn != nil {
   421  		return conn, nil
   422  	}
   423  
   424  	one := net.getNode(oneID)
   425  	if one == nil {
   426  		return nil, fmt.Errorf("node %v does not exist", oneID)
   427  	}
   428  	other := net.getNode(otherID)
   429  	if other == nil {
   430  		return nil, fmt.Errorf("node %v does not exist", otherID)
   431  	}
   432  	conn := &Conn{
   433  		One:   oneID,
   434  		Other: otherID,
   435  		one:   one,
   436  		other: other,
   437  	}
   438  	label := ConnLabel(oneID, otherID)
   439  	net.connMap[label] = len(net.Conns)
   440  	net.Conns = append(net.Conns, conn)
   441  	return conn, nil
   442  }
   443  
   444  func (net *Network) getConn(oneID, otherID discover.NodeID) *Conn {
   445  	label := ConnLabel(oneID, otherID)
   446  	i, found := net.connMap[label]
   447  	if !found {
   448  		return nil
   449  	}
   450  	return net.Conns[i]
   451  }
   452  
   453  //initconn(一个,另一个)为
   454  //彼此对等,如果不存在则创建一个新的
   455  //节点顺序无关紧要,即conn(i,j)==conn(j,i)
   456  //它检查连接是否已经启动,以及节点是否正在运行
   457  //注:
   458  //它还检查最近是否有连接对等端的尝试
   459  //这是欺骗,因为模拟被用作甲骨文并知道
   460  //远程对等机尝试连接到一个节点,该节点随后将不会启动连接。
   461  func (net *Network) InitConn(oneID, otherID discover.NodeID) (*Conn, error) {
   462  	net.lock.Lock()
   463  	defer net.lock.Unlock()
   464  	if oneID == otherID {
   465  		return nil, fmt.Errorf("refusing to connect to self %v", oneID)
   466  	}
   467  	conn, err := net.getOrCreateConn(oneID, otherID)
   468  	if err != nil {
   469  		return nil, err
   470  	}
   471  	if conn.Up {
   472  		return nil, fmt.Errorf("%v and %v already connected", oneID, otherID)
   473  	}
   474  	if time.Since(conn.initiated) < DialBanTimeout {
   475  		return nil, fmt.Errorf("connection between %v and %v recently attempted", oneID, otherID)
   476  	}
   477  
   478  	err = conn.nodesUp()
   479  	if err != nil {
   480  		log.Trace(fmt.Sprintf("nodes not up: %v", err))
   481  		return nil, fmt.Errorf("nodes not up: %v", err)
   482  	}
   483  	log.Debug("InitConn - connection initiated")
   484  	conn.initiated = time.Now()
   485  	return conn, nil
   486  }
   487  
   488  //shutdown停止网络中的所有节点并关闭退出通道
   489  func (net *Network) Shutdown() {
   490  	for _, node := range net.Nodes {
   491  		log.Debug(fmt.Sprintf("stopping node %s", node.ID().TerminalString()))
   492  		if err := node.Stop(); err != nil {
   493  			log.Warn(fmt.Sprintf("error stopping node %s", node.ID().TerminalString()), "err", err)
   494  		}
   495  	}
   496  	close(net.quitc)
   497  }
   498  
   499  //重置重置所有网络属性:
   500  //emtpies节点和连接列表
   501  func (net *Network) Reset() {
   502  	net.lock.Lock()
   503  	defer net.lock.Unlock()
   504  
   505  //重新初始化映射
   506  	net.connMap = make(map[string]int)
   507  	net.nodeMap = make(map[discover.NodeID]int)
   508  
   509  	net.Nodes = nil
   510  	net.Conns = nil
   511  }
   512  
   513  //node是围绕adapters.node的包装器,用于跟踪状态
   514  //网络中节点的
   515  type Node struct {
   516  	adapters.Node `json:"-"`
   517  
   518  //如果用于创建节点的配置
   519  	Config *adapters.NodeConfig `json:"config"`
   520  
   521  //向上跟踪节点是否正在运行
   522  	Up bool `json:"up"`
   523  }
   524  
   525  //ID返回节点的ID
   526  func (n *Node) ID() discover.NodeID {
   527  	return n.Config.ID
   528  }
   529  
   530  //字符串返回日志友好的字符串
   531  func (n *Node) String() string {
   532  	return fmt.Sprintf("Node %v", n.ID().TerminalString())
   533  }
   534  
   535  //nodeinfo返回有关节点的信息
   536  func (n *Node) NodeInfo() *p2p.NodeInfo {
   537  //如果节点尚未启动,请避免出现恐慌。
   538  	if n.Node == nil {
   539  		return nil
   540  	}
   541  	info := n.Node.NodeInfo()
   542  	info.Name = n.Config.Name
   543  	return info
   544  }
   545  
   546  //marshaljson实现json.marshaler接口,以便
   547  //json包括nodeinfo
   548  func (n *Node) MarshalJSON() ([]byte, error) {
   549  	return json.Marshal(struct {
   550  		Info   *p2p.NodeInfo        `json:"info,omitempty"`
   551  		Config *adapters.NodeConfig `json:"config,omitempty"`
   552  		Up     bool                 `json:"up"`
   553  	}{
   554  		Info:   n.NodeInfo(),
   555  		Config: n.Config,
   556  		Up:     n.Up,
   557  	})
   558  }
   559  
   560  //conn表示网络中两个节点之间的连接
   561  type Conn struct {
   562  //一个是启动连接的节点
   563  	One discover.NodeID `json:"one"`
   564  
   565  //另一个是连接到的节点
   566  	Other discover.NodeID `json:"other"`
   567  
   568  //向上跟踪连接是否处于活动状态
   569  	Up bool `json:"up"`
   570  //当连接被抓取拨号时注册
   571  	initiated time.Time
   572  
   573  	one   *Node
   574  	other *Node
   575  }
   576  
   577  //nodes up返回两个节点当前是否都已启动
   578  func (c *Conn) nodesUp() error {
   579  	if !c.one.Up {
   580  		return fmt.Errorf("one %v is not up", c.One)
   581  	}
   582  	if !c.other.Up {
   583  		return fmt.Errorf("other %v is not up", c.Other)
   584  	}
   585  	return nil
   586  }
   587  
   588  //字符串返回日志友好的字符串
   589  func (c *Conn) String() string {
   590  	return fmt.Sprintf("Conn %v->%v", c.One.TerminalString(), c.Other.TerminalString())
   591  }
   592  
   593  //msg表示网络中两个节点之间发送的P2P消息
   594  type Msg struct {
   595  	One      discover.NodeID `json:"one"`
   596  	Other    discover.NodeID `json:"other"`
   597  	Protocol string          `json:"protocol"`
   598  	Code     uint64          `json:"code"`
   599  	Received bool            `json:"received"`
   600  }
   601  
   602  //字符串返回日志友好的字符串
   603  func (m *Msg) String() string {
   604  	return fmt.Sprintf("Msg(%d) %v->%v", m.Code, m.One.TerminalString(), m.Other.TerminalString())
   605  }
   606  
   607  //connlabel生成表示连接的确定字符串
   608  //两个节点之间,用于比较两个连接是否相同
   609  //结点
   610  func ConnLabel(source, target discover.NodeID) string {
   611  	var first, second discover.NodeID
   612  	if bytes.Compare(source.Bytes(), target.Bytes()) > 0 {
   613  		first = target
   614  		second = source
   615  	} else {
   616  		first = source
   617  		second = target
   618  	}
   619  	return fmt.Sprintf("%v-%v", first, second)
   620  }
   621  
   622  //快照表示网络在单个时间点的状态,可以
   623  //用于恢复网络状态
   624  type Snapshot struct {
   625  	Nodes []NodeSnapshot `json:"nodes,omitempty"`
   626  	Conns []Conn         `json:"conns,omitempty"`
   627  }
   628  
   629  //nodesnapshot表示网络中节点的状态
   630  type NodeSnapshot struct {
   631  	Node Node `json:"node,omitempty"`
   632  
   633  //快照是从调用节点收集的任意数据。快照()
   634  	Snapshots map[string][]byte `json:"snapshots,omitempty"`
   635  }
   636  
   637  //快照创建网络快照
   638  func (net *Network) Snapshot() (*Snapshot, error) {
   639  	net.lock.Lock()
   640  	defer net.lock.Unlock()
   641  	snap := &Snapshot{
   642  		Nodes: make([]NodeSnapshot, len(net.Nodes)),
   643  		Conns: make([]Conn, len(net.Conns)),
   644  	}
   645  	for i, node := range net.Nodes {
   646  		snap.Nodes[i] = NodeSnapshot{Node: *node}
   647  		if !node.Up {
   648  			continue
   649  		}
   650  		snapshots, err := node.Snapshots()
   651  		if err != nil {
   652  			return nil, err
   653  		}
   654  		snap.Nodes[i].Snapshots = snapshots
   655  	}
   656  	for i, conn := range net.Conns {
   657  		snap.Conns[i] = *conn
   658  	}
   659  	return snap, nil
   660  }
   661  
   662  //加载加载网络快照
   663  func (net *Network) Load(snap *Snapshot) error {
   664  	for _, n := range snap.Nodes {
   665  		if _, err := net.NewNodeWithConfig(n.Node.Config); err != nil {
   666  			return err
   667  		}
   668  		if !n.Node.Up {
   669  			continue
   670  		}
   671  		if err := net.startWithSnapshots(n.Node.Config.ID, n.Snapshots); err != nil {
   672  			return err
   673  		}
   674  	}
   675  	for _, conn := range snap.Conns {
   676  
   677  		if !net.GetNode(conn.One).Up || !net.GetNode(conn.Other).Up {
   678  //在这种情况下,连接的至少一个节点没有启动,
   679  //所以会导致快照“加载”失败
   680  			continue
   681  		}
   682  		if err := net.Connect(conn.One, conn.Other); err != nil {
   683  			return err
   684  		}
   685  	}
   686  	return nil
   687  }
   688  
   689  //订阅从通道读取控制事件并执行它们
   690  func (net *Network) Subscribe(events chan *Event) {
   691  	for {
   692  		select {
   693  		case event, ok := <-events:
   694  			if !ok {
   695  				return
   696  			}
   697  			if event.Control {
   698  				net.executeControlEvent(event)
   699  			}
   700  		case <-net.quitc:
   701  			return
   702  		}
   703  	}
   704  }
   705  
   706  func (net *Network) executeControlEvent(event *Event) {
   707  	log.Trace("execute control event", "type", event.Type, "event", event)
   708  	switch event.Type {
   709  	case EventTypeNode:
   710  		if err := net.executeNodeEvent(event); err != nil {
   711  			log.Error("error executing node event", "event", event, "err", err)
   712  		}
   713  	case EventTypeConn:
   714  		if err := net.executeConnEvent(event); err != nil {
   715  			log.Error("error executing conn event", "event", event, "err", err)
   716  		}
   717  	case EventTypeMsg:
   718  		log.Warn("ignoring control msg event")
   719  	}
   720  }
   721  
   722  func (net *Network) executeNodeEvent(e *Event) error {
   723  	if !e.Node.Up {
   724  		return net.Stop(e.Node.ID())
   725  	}
   726  
   727  	if _, err := net.NewNodeWithConfig(e.Node.Config); err != nil {
   728  		return err
   729  	}
   730  	return net.Start(e.Node.ID())
   731  }
   732  
   733  func (net *Network) executeConnEvent(e *Event) error {
   734  	if e.Conn.Up {
   735  		return net.Connect(e.Conn.One, e.Conn.Other)
   736  	} else {
   737  		return net.Disconnect(e.Conn.One, e.Conn.Other)
   738  	}
   739  }
   740