github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/p2p/simulations/network_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  //版权所有2017 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 simulations
    26  
    27  import (
    28  	"context"
    29  	"fmt"
    30  	"testing"
    31  	"time"
    32  
    33  	"github.com/ethereum/go-ethereum/p2p/discover"
    34  	"github.com/ethereum/go-ethereum/p2p/simulations/adapters"
    35  )
    36  
    37  //TestNetworkSimulation使用每个节点创建多节点仿真网络
    38  //在环形拓扑中连接,检查所有节点是否成功握手
    39  //彼此之间,快照完全代表所需的拓扑
    40  func TestNetworkSimulation(t *testing.T) {
    41  //使用20个testservice节点创建模拟网络
    42  	adapter := adapters.NewSimAdapter(adapters.Services{
    43  		"test": newTestService,
    44  	})
    45  	network := NewNetwork(adapter, &NetworkConfig{
    46  		DefaultService: "test",
    47  	})
    48  	defer network.Shutdown()
    49  	nodeCount := 20
    50  	ids := make([]discover.NodeID, nodeCount)
    51  	for i := 0; i < nodeCount; i++ {
    52  		conf := adapters.RandomNodeConfig()
    53  		node, err := network.NewNodeWithConfig(conf)
    54  		if err != nil {
    55  			t.Fatalf("error creating node: %s", err)
    56  		}
    57  		if err := network.Start(node.ID()); err != nil {
    58  			t.Fatalf("error starting node: %s", err)
    59  		}
    60  		ids[i] = node.ID()
    61  	}
    62  
    63  //执行连接环中节点的检查(因此每个节点
    64  //然后检查所有节点
    65  //通过检查他们的对等计数进行了两次握手
    66  	action := func(_ context.Context) error {
    67  		for i, id := range ids {
    68  			peerID := ids[(i+1)%len(ids)]
    69  			if err := network.Connect(id, peerID); err != nil {
    70  				return err
    71  			}
    72  		}
    73  		return nil
    74  	}
    75  	check := func(ctx context.Context, id discover.NodeID) (bool, error) {
    76  //检查一下我们的时间没有用完
    77  		select {
    78  		case <-ctx.Done():
    79  			return false, ctx.Err()
    80  		default:
    81  		}
    82  
    83  //获取节点
    84  		node := network.GetNode(id)
    85  		if node == nil {
    86  			return false, fmt.Errorf("unknown node: %s", id)
    87  		}
    88  
    89  //检查它是否有两个同龄人
    90  		client, err := node.Client()
    91  		if err != nil {
    92  			return false, err
    93  		}
    94  		var peerCount int64
    95  		if err := client.CallContext(ctx, &peerCount, "test_peerCount"); err != nil {
    96  			return false, err
    97  		}
    98  		switch {
    99  		case peerCount < 2:
   100  			return false, nil
   101  		case peerCount == 2:
   102  			return true, nil
   103  		default:
   104  			return false, fmt.Errorf("unexpected peerCount: %d", peerCount)
   105  		}
   106  	}
   107  
   108  	timeout := 30 * time.Second
   109  	ctx, cancel := context.WithTimeout(context.Background(), timeout)
   110  	defer cancel()
   111  
   112  //每100毫秒触发一次检查
   113  	trigger := make(chan discover.NodeID)
   114  	go triggerChecks(ctx, ids, trigger, 100*time.Millisecond)
   115  
   116  	result := NewSimulation(network).Run(ctx, &Step{
   117  		Action:  action,
   118  		Trigger: trigger,
   119  		Expect: &Expectation{
   120  			Nodes: ids,
   121  			Check: check,
   122  		},
   123  	})
   124  	if result.Error != nil {
   125  		t.Fatalf("simulation failed: %s", result.Error)
   126  	}
   127  
   128  //获取网络快照并检查它是否包含正确的拓扑
   129  	snap, err := network.Snapshot()
   130  	if err != nil {
   131  		t.Fatal(err)
   132  	}
   133  	if len(snap.Nodes) != nodeCount {
   134  		t.Fatalf("expected snapshot to contain %d nodes, got %d", nodeCount, len(snap.Nodes))
   135  	}
   136  	if len(snap.Conns) != nodeCount {
   137  		t.Fatalf("expected snapshot to contain %d connections, got %d", nodeCount, len(snap.Conns))
   138  	}
   139  	for i, id := range ids {
   140  		conn := snap.Conns[i]
   141  		if conn.One != id {
   142  			t.Fatalf("expected conn[%d].One to be %s, got %s", i, id, conn.One)
   143  		}
   144  		peerID := ids[(i+1)%len(ids)]
   145  		if conn.Other != peerID {
   146  			t.Fatalf("expected conn[%d].Other to be %s, got %s", i, peerID, conn.Other)
   147  		}
   148  	}
   149  }
   150  
   151  func triggerChecks(ctx context.Context, ids []discover.NodeID, trigger chan discover.NodeID, interval time.Duration) {
   152  	tick := time.NewTicker(interval)
   153  	defer tick.Stop()
   154  	for {
   155  		select {
   156  		case <-tick.C:
   157  			for _, id := range ids {
   158  				select {
   159  				case trigger <- id:
   160  				case <-ctx.Done():
   161  					return
   162  				}
   163  			}
   164  		case <-ctx.Done():
   165  			return
   166  		}
   167  	}
   168  }