github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/swarm/network/networkid_test.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 //版权所有2018 Go Ethereum作者 10 //此文件是Go以太坊库的一部分。 11 // 12 //Go-Ethereum库是免费软件:您可以重新分发它和/或修改 13 //根据GNU发布的较低通用公共许可证的条款 14 //自由软件基金会,或者许可证的第3版,或者 15 //(由您选择)任何更高版本。 16 // 17 //Go以太坊图书馆的发行目的是希望它会有用, 18 //但没有任何保证;甚至没有 19 //适销性或特定用途的适用性。见 20 //GNU较低的通用公共许可证,了解更多详细信息。 21 // 22 //你应该收到一份GNU较低级别的公共许可证副本 23 //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。 24 25 package network 26 27 import ( 28 "bytes" 29 "context" 30 "flag" 31 "fmt" 32 "math/rand" 33 "strings" 34 "testing" 35 "time" 36 37 "github.com/ethereum/go-ethereum/log" 38 "github.com/ethereum/go-ethereum/node" 39 "github.com/ethereum/go-ethereum/p2p" 40 "github.com/ethereum/go-ethereum/p2p/discover" 41 "github.com/ethereum/go-ethereum/p2p/simulations" 42 "github.com/ethereum/go-ethereum/p2p/simulations/adapters" 43 "github.com/ethereum/go-ethereum/rpc" 44 ) 45 46 var ( 47 currentNetworkID int 48 cnt int 49 nodeMap map[int][]discover.NodeID 50 kademlias map[discover.NodeID]*Kademlia 51 ) 52 53 const ( 54 NumberOfNets = 4 55 MaxTimeout = 6 56 ) 57 58 func init() { 59 flag.Parse() 60 rand.Seed(time.Now().Unix()) 61 } 62 63 /* 64 运行网络ID测试。 65 测试创建一个模拟。网络实例, 66 多个节点,然后在此网络中彼此连接节点。 67 68 每个节点都得到一个根据网络数量分配的网络ID。 69 拥有更多的网络ID只是为了排除 70 误报。 71 72 节点只能与具有相同网络ID的其他节点连接。 73 在设置阶段之后,测试将检查每个节点是否具有 74 预期的节点连接(不包括那些不共享网络ID的连接)。 75 **/ 76 77 func TestNetworkID(t *testing.T) { 78 log.Debug("Start test") 79 //任意设置节点数。可以是任何号码 80 numNodes := 24 81 //nodemap用相同的网络ID(key)映射所有节点(切片值) 82 nodeMap = make(map[int][]discover.NodeID) 83 //设置网络并连接节点 84 net, err := setupNetwork(numNodes) 85 if err != nil { 86 t.Fatalf("Error setting up network: %v", err) 87 } 88 defer func() { 89 //关闭快照网络 90 log.Trace("Shutting down network") 91 net.Shutdown() 92 }() 93 //让我们休眠以确保所有节点都已连接 94 time.Sleep(1 * time.Second) 95 //对于共享相同网络ID的每个组… 96 for _, netIDGroup := range nodeMap { 97 log.Trace("netIDGroup size", "size", len(netIDGroup)) 98 //…检查他们的花冠尺寸是否符合预期尺寸 99 //假设它应该是组的大小减去1(节点本身)。 100 for _, node := range netIDGroup { 101 if kademlias[node].addrs.Size() != len(netIDGroup)-1 { 102 t.Fatalf("Kademlia size has not expected peer size. Kademlia size: %d, expected size: %d", kademlias[node].addrs.Size(), len(netIDGroup)-1) 103 } 104 kademlias[node].EachAddr(nil, 0, func(addr OverlayAddr, _ int, _ bool) bool { 105 found := false 106 for _, nd := range netIDGroup { 107 p := ToOverlayAddr(nd.Bytes()) 108 if bytes.Equal(p, addr.Address()) { 109 found = true 110 } 111 } 112 if !found { 113 t.Fatalf("Expected node not found for node %s", node.String()) 114 } 115 return true 116 }) 117 } 118 } 119 log.Info("Test terminated successfully") 120 } 121 122 //使用bzz/discovery和pss服务设置模拟网络。 123 //连接圆中的节点 124 //如果设置了allowraw,则启用了省略内置PSS加密(请参阅PSSPARAMS) 125 func setupNetwork(numnodes int) (net *simulations.Network, err error) { 126 log.Debug("Setting up network") 127 quitC := make(chan struct{}) 128 errc := make(chan error) 129 nodes := make([]*simulations.Node, numnodes) 130 if numnodes < 16 { 131 return nil, fmt.Errorf("Minimum sixteen nodes in network") 132 } 133 adapter := adapters.NewSimAdapter(newServices()) 134 //创建网络 135 net = simulations.NewNetwork(adapter, &simulations.NetworkConfig{ 136 ID: "NetworkIdTestNet", 137 DefaultService: "bzz", 138 }) 139 log.Debug("Creating networks and nodes") 140 141 var connCount int 142 143 //创建节点并相互连接 144 for i := 0; i < numnodes; i++ { 145 log.Trace("iteration: ", "i", i) 146 nodeconf := adapters.RandomNodeConfig() 147 nodes[i], err = net.NewNodeWithConfig(nodeconf) 148 if err != nil { 149 return nil, fmt.Errorf("error creating node %d: %v", i, err) 150 } 151 err = net.Start(nodes[i].ID()) 152 if err != nil { 153 return nil, fmt.Errorf("error starting node %d: %v", i, err) 154 } 155 client, err := nodes[i].Client() 156 if err != nil { 157 return nil, fmt.Errorf("create node %d rpc client fail: %v", i, err) 158 } 159 //现在设置并开始事件监视,以了解何时可以上载 160 ctx, watchCancel := context.WithTimeout(context.Background(), MaxTimeout*time.Second) 161 defer watchCancel() 162 watchSubscriptionEvents(ctx, nodes[i].ID(), client, errc, quitC) 163 //在每次迭代中,我们都连接到以前的所有迭代 164 for k := i - 1; k >= 0; k-- { 165 connCount++ 166 log.Debug(fmt.Sprintf("Connecting node %d with node %d; connection count is %d", i, k, connCount)) 167 err = net.Connect(nodes[i].ID(), nodes[k].ID()) 168 if err != nil { 169 if !strings.Contains(err.Error(), "already connected") { 170 return nil, fmt.Errorf("error connecting nodes: %v", err) 171 } 172 } 173 } 174 } 175 //现在等待,直到完成预期订阅的数量 176 //`watchsubscriptionEvents`将用'nil'值写入errc 177 for err := range errc { 178 if err != nil { 179 return nil, err 180 } 181 //收到“nil”,递减计数 182 connCount-- 183 log.Trace("count down", "cnt", connCount) 184 //收到的所有订阅 185 if connCount == 0 { 186 close(quitC) 187 break 188 } 189 } 190 log.Debug("Network setup phase terminated") 191 return net, nil 192 } 193 194 func newServices() adapters.Services { 195 kademlias = make(map[discover.NodeID]*Kademlia) 196 kademlia := func(id discover.NodeID) *Kademlia { 197 if k, ok := kademlias[id]; ok { 198 return k 199 } 200 addr := NewAddrFromNodeID(id) 201 params := NewKadParams() 202 params.MinProxBinSize = 2 203 params.MaxBinSize = 3 204 params.MinBinSize = 1 205 params.MaxRetries = 1000 206 params.RetryExponent = 2 207 params.RetryInterval = 1000000 208 kademlias[id] = NewKademlia(addr.Over(), params) 209 return kademlias[id] 210 } 211 return adapters.Services{ 212 "bzz": func(ctx *adapters.ServiceContext) (node.Service, error) { 213 addr := NewAddrFromNodeID(ctx.Config.ID) 214 hp := NewHiveParams() 215 hp.Discovery = false 216 cnt++ 217 //分配网络ID 218 currentNetworkID = cnt % NumberOfNets 219 if ok := nodeMap[currentNetworkID]; ok == nil { 220 nodeMap[currentNetworkID] = make([]discover.NodeID, 0) 221 } 222 //将此节点添加到共享相同网络ID的组中 223 nodeMap[currentNetworkID] = append(nodeMap[currentNetworkID], ctx.Config.ID) 224 log.Debug("current network ID:", "id", currentNetworkID) 225 config := &BzzConfig{ 226 OverlayAddr: addr.Over(), 227 UnderlayAddr: addr.Under(), 228 HiveParams: hp, 229 NetworkID: uint64(currentNetworkID), 230 } 231 return NewBzz(config, kademlia(ctx.Config.ID), nil, nil, nil), nil 232 }, 233 } 234 } 235 236 func watchSubscriptionEvents(ctx context.Context, id discover.NodeID, client *rpc.Client, errc chan error, quitC chan struct{}) { 237 events := make(chan *p2p.PeerEvent) 238 sub, err := client.Subscribe(context.Background(), "admin", events, "peerEvents") 239 if err != nil { 240 log.Error(err.Error()) 241 errc <- fmt.Errorf("error getting peer events for node %v: %s", id, err) 242 return 243 } 244 go func() { 245 defer func() { 246 sub.Unsubscribe() 247 log.Trace("watch subscription events: unsubscribe", "id", id) 248 }() 249 250 for { 251 select { 252 case <-quitC: 253 return 254 case <-ctx.Done(): 255 select { 256 case errc <- ctx.Err(): 257 case <-quitC: 258 } 259 return 260 case e := <-events: 261 if e.Type == p2p.PeerEventTypeAdd { 262 errc <- nil 263 } 264 case err := <-sub.Err(): 265 if err != nil { 266 select { 267 case errc <- fmt.Errorf("error getting peer events for node %v: %v", id, err): 268 case <-quitC: 269 } 270 return 271 } 272 } 273 } 274 }() 275 }