github.com/shyftnetwork/go-empyrean@v1.8.3-0.20191127201940-fbfca9338f04/swarm/network/protocol_test.go (about)

     1  // Copyright 2016 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package network
    18  
    19  import (
    20  	"flag"
    21  	"fmt"
    22  	"os"
    23  	"testing"
    24  
    25  	"github.com/ShyftNetwork/go-empyrean/log"
    26  	"github.com/ShyftNetwork/go-empyrean/p2p"
    27  	"github.com/ShyftNetwork/go-empyrean/p2p/enode"
    28  	"github.com/ShyftNetwork/go-empyrean/p2p/protocols"
    29  	p2ptest "github.com/ShyftNetwork/go-empyrean/p2p/testing"
    30  )
    31  
    32  const (
    33  	TestProtocolVersion   = 8
    34  	TestProtocolNetworkID = 3
    35  )
    36  
    37  var (
    38  	loglevel = flag.Int("loglevel", 2, "verbosity of logs")
    39  )
    40  
    41  func init() {
    42  	flag.Parse()
    43  	log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(os.Stderr, log.TerminalFormat(true))))
    44  }
    45  
    46  func HandshakeMsgExchange(lhs, rhs *HandshakeMsg, id enode.ID) []p2ptest.Exchange {
    47  	return []p2ptest.Exchange{
    48  		{
    49  			Expects: []p2ptest.Expect{
    50  				{
    51  					Code: 0,
    52  					Msg:  lhs,
    53  					Peer: id,
    54  				},
    55  			},
    56  		},
    57  		{
    58  			Triggers: []p2ptest.Trigger{
    59  				{
    60  					Code: 0,
    61  					Msg:  rhs,
    62  					Peer: id,
    63  				},
    64  			},
    65  		},
    66  	}
    67  }
    68  
    69  func newBzzBaseTester(t *testing.T, n int, addr *BzzAddr, spec *protocols.Spec, run func(*BzzPeer) error) *bzzTester {
    70  	cs := make(map[string]chan bool)
    71  
    72  	srv := func(p *BzzPeer) error {
    73  		defer func() {
    74  			if cs[p.ID().String()] != nil {
    75  				close(cs[p.ID().String()])
    76  			}
    77  		}()
    78  		return run(p)
    79  	}
    80  
    81  	protocol := func(p *p2p.Peer, rw p2p.MsgReadWriter) error {
    82  		return srv(&BzzPeer{Peer: protocols.NewPeer(p, rw, spec), BzzAddr: NewAddr(p.Node())})
    83  	}
    84  
    85  	s := p2ptest.NewProtocolTester(t, addr.ID(), n, protocol)
    86  
    87  	for _, node := range s.Nodes {
    88  		cs[node.ID().String()] = make(chan bool)
    89  	}
    90  
    91  	return &bzzTester{
    92  		addr:           addr,
    93  		ProtocolTester: s,
    94  		cs:             cs,
    95  	}
    96  }
    97  
    98  type bzzTester struct {
    99  	*p2ptest.ProtocolTester
   100  	addr *BzzAddr
   101  	cs   map[string]chan bool
   102  	bzz  *Bzz
   103  }
   104  
   105  func newBzz(addr *BzzAddr, lightNode bool) *Bzz {
   106  	config := &BzzConfig{
   107  		OverlayAddr:  addr.Over(),
   108  		UnderlayAddr: addr.Under(),
   109  		HiveParams:   NewHiveParams(),
   110  		NetworkID:    DefaultNetworkID,
   111  		LightNode:    lightNode,
   112  	}
   113  	kad := NewKademlia(addr.OAddr, NewKadParams())
   114  	bzz := NewBzz(config, kad, nil, nil, nil)
   115  	return bzz
   116  }
   117  
   118  func newBzzHandshakeTester(t *testing.T, n int, addr *BzzAddr, lightNode bool) *bzzTester {
   119  	bzz := newBzz(addr, lightNode)
   120  	pt := p2ptest.NewProtocolTester(t, addr.ID(), n, bzz.runBzz)
   121  
   122  	return &bzzTester{
   123  		addr:           addr,
   124  		ProtocolTester: pt,
   125  		bzz:            bzz,
   126  	}
   127  }
   128  
   129  // should test handshakes in one exchange? parallelisation
   130  func (s *bzzTester) testHandshake(lhs, rhs *HandshakeMsg, disconnects ...*p2ptest.Disconnect) error {
   131  	if err := s.TestExchanges(HandshakeMsgExchange(lhs, rhs, rhs.Addr.ID())...); err != nil {
   132  		return err
   133  	}
   134  
   135  	if len(disconnects) > 0 {
   136  		return s.TestDisconnected(disconnects...)
   137  	}
   138  
   139  	// If we don't expect disconnect, ensure peers remain connected
   140  	err := s.TestDisconnected(&p2ptest.Disconnect{
   141  		Peer:  s.Nodes[0].ID(),
   142  		Error: nil,
   143  	})
   144  
   145  	if err == nil {
   146  		return fmt.Errorf("Unexpected peer disconnect")
   147  	}
   148  
   149  	if err.Error() != "timed out waiting for peers to disconnect" {
   150  		return err
   151  	}
   152  
   153  	return nil
   154  }
   155  
   156  func correctBzzHandshake(addr *BzzAddr, lightNode bool) *HandshakeMsg {
   157  	return &HandshakeMsg{
   158  		Version:   TestProtocolVersion,
   159  		NetworkID: TestProtocolNetworkID,
   160  		Addr:      addr,
   161  		LightNode: lightNode,
   162  	}
   163  }
   164  
   165  func TestBzzHandshakeNetworkIDMismatch(t *testing.T) {
   166  	lightNode := false
   167  	addr := RandomAddr()
   168  	s := newBzzHandshakeTester(t, 1, addr, lightNode)
   169  	node := s.Nodes[0]
   170  
   171  	err := s.testHandshake(
   172  		correctBzzHandshake(addr, lightNode),
   173  		&HandshakeMsg{Version: TestProtocolVersion, NetworkID: 321, Addr: NewAddr(node)},
   174  		&p2ptest.Disconnect{Peer: node.ID(), Error: fmt.Errorf("Handshake error: Message handler error: (msg code 0): network id mismatch 321 (!= 3)")},
   175  	)
   176  
   177  	if err != nil {
   178  		t.Fatal(err)
   179  	}
   180  }
   181  
   182  func TestBzzHandshakeVersionMismatch(t *testing.T) {
   183  	lightNode := false
   184  	addr := RandomAddr()
   185  	s := newBzzHandshakeTester(t, 1, addr, lightNode)
   186  	node := s.Nodes[0]
   187  
   188  	err := s.testHandshake(
   189  		correctBzzHandshake(addr, lightNode),
   190  		&HandshakeMsg{Version: 0, NetworkID: TestProtocolNetworkID, Addr: NewAddr(node)},
   191  		&p2ptest.Disconnect{Peer: node.ID(), Error: fmt.Errorf("Handshake error: Message handler error: (msg code 0): version mismatch 0 (!= %d)", TestProtocolVersion)},
   192  	)
   193  
   194  	if err != nil {
   195  		t.Fatal(err)
   196  	}
   197  }
   198  
   199  func TestBzzHandshakeSuccess(t *testing.T) {
   200  	lightNode := false
   201  	addr := RandomAddr()
   202  	s := newBzzHandshakeTester(t, 1, addr, lightNode)
   203  	node := s.Nodes[0]
   204  
   205  	err := s.testHandshake(
   206  		correctBzzHandshake(addr, lightNode),
   207  		&HandshakeMsg{Version: TestProtocolVersion, NetworkID: TestProtocolNetworkID, Addr: NewAddr(node)},
   208  	)
   209  
   210  	if err != nil {
   211  		t.Fatal(err)
   212  	}
   213  }
   214  
   215  func TestBzzHandshakeLightNode(t *testing.T) {
   216  	var lightNodeTests = []struct {
   217  		name      string
   218  		lightNode bool
   219  	}{
   220  		{"on", true},
   221  		{"off", false},
   222  	}
   223  
   224  	for _, test := range lightNodeTests {
   225  		t.Run(test.name, func(t *testing.T) {
   226  			randomAddr := RandomAddr()
   227  			pt := newBzzHandshakeTester(t, 1, randomAddr, false)
   228  			node := pt.Nodes[0]
   229  			addr := NewAddr(node)
   230  
   231  			err := pt.testHandshake(
   232  				correctBzzHandshake(randomAddr, false),
   233  				&HandshakeMsg{Version: TestProtocolVersion, NetworkID: TestProtocolNetworkID, Addr: addr, LightNode: test.lightNode},
   234  			)
   235  
   236  			if err != nil {
   237  				t.Fatal(err)
   238  			}
   239  
   240  			if pt.bzz.handshakes[node.ID()].LightNode != test.lightNode {
   241  				t.Fatalf("peer LightNode flag is %v, should be %v", pt.bzz.handshakes[node.ID()].LightNode, test.lightNode)
   242  			}
   243  		})
   244  	}
   245  }