github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/p2p/simulations/connect.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:41</date>
    10  //</624450106745163776>
    11  
    12  
    13  package simulations
    14  
    15  import (
    16  	"errors"
    17  	"strings"
    18  
    19  	"github.com/ethereum/go-ethereum/p2p/enode"
    20  )
    21  
    22  var (
    23  	ErrNodeNotFound = errors.New("node not found")
    24  )
    25  
    26  //ConnectToLastNode将节点与提供的节点ID连接起来
    27  //到上一个节点,并避免连接到自身。
    28  //它在构建链网络拓扑结构时很有用
    29  //当网络动态添加和删除节点时。
    30  func (net *Network) ConnectToLastNode(id enode.ID) (err error) {
    31  	ids := net.getUpNodeIDs()
    32  	l := len(ids)
    33  	if l < 2 {
    34  		return nil
    35  	}
    36  	last := ids[l-1]
    37  	if last == id {
    38  		last = ids[l-2]
    39  	}
    40  	return net.connect(last, id)
    41  }
    42  
    43  //connecttorandomnode将节点与提供的nodeid连接起来
    44  //向上的随机节点发送。
    45  func (net *Network) ConnectToRandomNode(id enode.ID) (err error) {
    46  	selected := net.GetRandomUpNode(id)
    47  	if selected == nil {
    48  		return ErrNodeNotFound
    49  	}
    50  	return net.connect(selected.ID(), id)
    51  }
    52  
    53  //ConnectNodesFull将所有节点连接到另一个。
    54  //它在网络中提供了完整的连接
    55  //这应该是很少需要的。
    56  func (net *Network) ConnectNodesFull(ids []enode.ID) (err error) {
    57  	if ids == nil {
    58  		ids = net.getUpNodeIDs()
    59  	}
    60  	for i, lid := range ids {
    61  		for _, rid := range ids[i+1:] {
    62  			if err = net.connect(lid, rid); err != nil {
    63  				return err
    64  			}
    65  		}
    66  	}
    67  	return nil
    68  }
    69  
    70  //connectnodeschain连接链拓扑中的所有节点。
    71  //如果ids参数为nil,则所有打开的节点都将被连接。
    72  func (net *Network) ConnectNodesChain(ids []enode.ID) (err error) {
    73  	if ids == nil {
    74  		ids = net.getUpNodeIDs()
    75  	}
    76  	l := len(ids)
    77  	for i := 0; i < l-1; i++ {
    78  		if err := net.connect(ids[i], ids[i+1]); err != nil {
    79  			return err
    80  		}
    81  	}
    82  	return nil
    83  }
    84  
    85  //ConnectNodesRing连接环拓扑中的所有节点。
    86  //如果ids参数为nil,则所有打开的节点都将被连接。
    87  func (net *Network) ConnectNodesRing(ids []enode.ID) (err error) {
    88  	if ids == nil {
    89  		ids = net.getUpNodeIDs()
    90  	}
    91  	l := len(ids)
    92  	if l < 2 {
    93  		return nil
    94  	}
    95  	if err := net.ConnectNodesChain(ids); err != nil {
    96  		return err
    97  	}
    98  	return net.connect(ids[l-1], ids[0])
    99  }
   100  
   101  //connectnodestar将所有节点连接到星形拓扑中
   102  //如果ids参数为nil,则所有打开的节点都将被连接。
   103  func (net *Network) ConnectNodesStar(ids []enode.ID, center enode.ID) (err error) {
   104  	if ids == nil {
   105  		ids = net.getUpNodeIDs()
   106  	}
   107  	for _, id := range ids {
   108  		if center == id {
   109  			continue
   110  		}
   111  		if err := net.connect(center, id); err != nil {
   112  			return err
   113  		}
   114  	}
   115  	return nil
   116  }
   117  
   118  //连接连接两个节点,但忽略已连接的错误。
   119  func (net *Network) connect(oneID, otherID enode.ID) error {
   120  	return ignoreAlreadyConnectedErr(net.Connect(oneID, otherID))
   121  }
   122  
   123  func ignoreAlreadyConnectedErr(err error) error {
   124  	if err == nil || strings.Contains(err.Error(), "already connected") {
   125  		return nil
   126  	}
   127  	return err
   128  }
   129