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