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