github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/swarm/network/protocol_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  //版权所有2016 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  	"flag"
    29  	"fmt"
    30  	"os"
    31  	"sync"
    32  	"testing"
    33  
    34  	"github.com/ethereum/go-ethereum/log"
    35  	"github.com/ethereum/go-ethereum/p2p"
    36  	"github.com/ethereum/go-ethereum/p2p/discover"
    37  	"github.com/ethereum/go-ethereum/p2p/protocols"
    38  	p2ptest "github.com/ethereum/go-ethereum/p2p/testing"
    39  )
    40  
    41  const (
    42  	TestProtocolVersion   = 6
    43  	TestProtocolNetworkID = 3
    44  )
    45  
    46  var (
    47  	loglevel = flag.Int("loglevel", 2, "verbosity of logs")
    48  )
    49  
    50  func init() {
    51  	flag.Parse()
    52  	log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(os.Stderr, log.TerminalFormat(true))))
    53  }
    54  
    55  type testStore struct {
    56  	sync.Mutex
    57  
    58  	values map[string][]byte
    59  }
    60  
    61  func newTestStore() *testStore {
    62  	return &testStore{values: make(map[string][]byte)}
    63  }
    64  
    65  func (t *testStore) Load(key string) ([]byte, error) {
    66  	t.Lock()
    67  	defer t.Unlock()
    68  	v, ok := t.values[key]
    69  	if !ok {
    70  		return nil, fmt.Errorf("key not found: %s", key)
    71  	}
    72  	return v, nil
    73  }
    74  
    75  func (t *testStore) Save(key string, v []byte) error {
    76  	t.Lock()
    77  	defer t.Unlock()
    78  	t.values[key] = v
    79  	return nil
    80  }
    81  
    82  func HandshakeMsgExchange(lhs, rhs *HandshakeMsg, id discover.NodeID) []p2ptest.Exchange {
    83  
    84  	return []p2ptest.Exchange{
    85  		{
    86  			Expects: []p2ptest.Expect{
    87  				{
    88  					Code: 0,
    89  					Msg:  lhs,
    90  					Peer: id,
    91  				},
    92  			},
    93  		},
    94  		{
    95  			Triggers: []p2ptest.Trigger{
    96  				{
    97  					Code: 0,
    98  					Msg:  rhs,
    99  					Peer: id,
   100  				},
   101  			},
   102  		},
   103  	}
   104  }
   105  
   106  func newBzzBaseTester(t *testing.T, n int, addr *BzzAddr, spec *protocols.Spec, run func(*BzzPeer) error) *bzzTester {
   107  	cs := make(map[string]chan bool)
   108  
   109  	srv := func(p *BzzPeer) error {
   110  		defer func() {
   111  			if cs[p.ID().String()] != nil {
   112  				close(cs[p.ID().String()])
   113  			}
   114  		}()
   115  		return run(p)
   116  	}
   117  
   118  	protocol := func(p *p2p.Peer, rw p2p.MsgReadWriter) error {
   119  		return srv(&BzzPeer{
   120  			Peer:      protocols.NewPeer(p, rw, spec),
   121  			localAddr: addr,
   122  			BzzAddr:   NewAddrFromNodeID(p.ID()),
   123  		})
   124  	}
   125  
   126  	s := p2ptest.NewProtocolTester(t, NewNodeIDFromAddr(addr), n, protocol)
   127  
   128  	for _, id := range s.IDs {
   129  		cs[id.String()] = make(chan bool)
   130  	}
   131  
   132  	return &bzzTester{
   133  		addr:           addr,
   134  		ProtocolTester: s,
   135  		cs:             cs,
   136  	}
   137  }
   138  
   139  type bzzTester struct {
   140  	*p2ptest.ProtocolTester
   141  	addr *BzzAddr
   142  	cs   map[string]chan bool
   143  	bzz  *Bzz
   144  }
   145  
   146  func newBzz(addr *BzzAddr, lightNode bool) *Bzz {
   147  	config := &BzzConfig{
   148  		OverlayAddr:  addr.Over(),
   149  		UnderlayAddr: addr.Under(),
   150  		HiveParams:   NewHiveParams(),
   151  		NetworkID:    DefaultNetworkID,
   152  		LightNode:    lightNode,
   153  	}
   154  	kad := NewKademlia(addr.OAddr, NewKadParams())
   155  	bzz := NewBzz(config, kad, nil, nil, nil)
   156  	return bzz
   157  }
   158  
   159  func newBzzHandshakeTester(t *testing.T, n int, addr *BzzAddr, lightNode bool) *bzzTester {
   160  	bzz := newBzz(addr, lightNode)
   161  	pt := p2ptest.NewProtocolTester(t, NewNodeIDFromAddr(addr), n, bzz.runBzz)
   162  
   163  	return &bzzTester{
   164  		addr:           addr,
   165  		ProtocolTester: pt,
   166  		bzz:            bzz,
   167  	}
   168  }
   169  
   170  //应该在一次交换中测试握手吗?并行化
   171  func (s *bzzTester) testHandshake(lhs, rhs *HandshakeMsg, disconnects ...*p2ptest.Disconnect) error {
   172  	var peers []discover.NodeID
   173  	id := NewNodeIDFromAddr(rhs.Addr)
   174  	if len(disconnects) > 0 {
   175  		for _, d := range disconnects {
   176  			peers = append(peers, d.Peer)
   177  		}
   178  	} else {
   179  		peers = []discover.NodeID{id}
   180  	}
   181  
   182  	if err := s.TestExchanges(HandshakeMsgExchange(lhs, rhs, id)...); err != nil {
   183  		return err
   184  	}
   185  
   186  	if len(disconnects) > 0 {
   187  		return s.TestDisconnected(disconnects...)
   188  	}
   189  
   190  //如果我们不期望断开连接,请确保对等端保持连接
   191  	err := s.TestDisconnected(&p2ptest.Disconnect{
   192  		Peer:  s.IDs[0],
   193  		Error: nil,
   194  	})
   195  
   196  	if err == nil {
   197  		return fmt.Errorf("Unexpected peer disconnect")
   198  	}
   199  
   200  	if err.Error() != "timed out waiting for peers to disconnect" {
   201  		return err
   202  	}
   203  
   204  	return nil
   205  }
   206  
   207  func correctBzzHandshake(addr *BzzAddr, lightNode bool) *HandshakeMsg {
   208  	return &HandshakeMsg{
   209  		Version:   TestProtocolVersion,
   210  		NetworkID: TestProtocolNetworkID,
   211  		Addr:      addr,
   212  		LightNode: lightNode,
   213  	}
   214  }
   215  
   216  func TestBzzHandshakeNetworkIDMismatch(t *testing.T) {
   217  	lightNode := false
   218  	addr := RandomAddr()
   219  	s := newBzzHandshakeTester(t, 1, addr, lightNode)
   220  	id := s.IDs[0]
   221  
   222  	err := s.testHandshake(
   223  		correctBzzHandshake(addr, lightNode),
   224  		&HandshakeMsg{Version: TestProtocolVersion, NetworkID: 321, Addr: NewAddrFromNodeID(id)},
   225  		&p2ptest.Disconnect{Peer: id, Error: fmt.Errorf("Handshake error: Message handler error: (msg code 0): network id mismatch 321 (!= 3)")},
   226  	)
   227  
   228  	if err != nil {
   229  		t.Fatal(err)
   230  	}
   231  }
   232  
   233  func TestBzzHandshakeVersionMismatch(t *testing.T) {
   234  	lightNode := false
   235  	addr := RandomAddr()
   236  	s := newBzzHandshakeTester(t, 1, addr, lightNode)
   237  	id := s.IDs[0]
   238  
   239  	err := s.testHandshake(
   240  		correctBzzHandshake(addr, lightNode),
   241  		&HandshakeMsg{Version: 0, NetworkID: TestProtocolNetworkID, Addr: NewAddrFromNodeID(id)},
   242  		&p2ptest.Disconnect{Peer: id, Error: fmt.Errorf("Handshake error: Message handler error: (msg code 0): version mismatch 0 (!= %d)", TestProtocolVersion)},
   243  	)
   244  
   245  	if err != nil {
   246  		t.Fatal(err)
   247  	}
   248  }
   249  
   250  func TestBzzHandshakeSuccess(t *testing.T) {
   251  	lightNode := false
   252  	addr := RandomAddr()
   253  	s := newBzzHandshakeTester(t, 1, addr, lightNode)
   254  	id := s.IDs[0]
   255  
   256  	err := s.testHandshake(
   257  		correctBzzHandshake(addr, lightNode),
   258  		&HandshakeMsg{Version: TestProtocolVersion, NetworkID: TestProtocolNetworkID, Addr: NewAddrFromNodeID(id)},
   259  	)
   260  
   261  	if err != nil {
   262  		t.Fatal(err)
   263  	}
   264  }
   265  
   266  func TestBzzHandshakeLightNode(t *testing.T) {
   267  	var lightNodeTests = []struct {
   268  		name      string
   269  		lightNode bool
   270  	}{
   271  		{"on", true},
   272  		{"off", false},
   273  	}
   274  
   275  	for _, test := range lightNodeTests {
   276  		t.Run(test.name, func(t *testing.T) {
   277  			randomAddr := RandomAddr()
   278  			pt := newBzzHandshakeTester(t, 1, randomAddr, false)
   279  			id := pt.IDs[0]
   280  			addr := NewAddrFromNodeID(id)
   281  
   282  			err := pt.testHandshake(
   283  				correctBzzHandshake(randomAddr, false),
   284  				&HandshakeMsg{Version: TestProtocolVersion, NetworkID: TestProtocolNetworkID, Addr: addr, LightNode: test.lightNode},
   285  			)
   286  
   287  			if err != nil {
   288  				t.Fatal(err)
   289  			}
   290  
   291  			if pt.bzz.handshakes[id].LightNode != test.lightNode {
   292  				t.Fatalf("peer LightNode flag is %v, should be %v", pt.bzz.handshakes[id].LightNode, test.lightNode)
   293  			}
   294  		})
   295  	}
   296  }