github.com/evdatsion/aphelion-dpos-bft@v0.32.1/p2p/transport_test.go (about)

     1  package p2p
     2  
     3  import (
     4  	"fmt"
     5  	"math/rand"
     6  	"net"
     7  	"reflect"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/evdatsion/aphelion-dpos-bft/crypto/ed25519"
    12  	"github.com/evdatsion/aphelion-dpos-bft/p2p/conn"
    13  )
    14  
    15  var defaultNodeName = "host_peer"
    16  
    17  func emptyNodeInfo() NodeInfo {
    18  	return DefaultNodeInfo{}
    19  }
    20  
    21  // newMultiplexTransport returns a tcp connected multiplexed peer
    22  // using the default MConnConfig. It's a convenience function used
    23  // for testing.
    24  func newMultiplexTransport(
    25  	nodeInfo NodeInfo,
    26  	nodeKey NodeKey,
    27  ) *MultiplexTransport {
    28  	return NewMultiplexTransport(
    29  		nodeInfo, nodeKey, conn.DefaultMConnConfig(),
    30  	)
    31  }
    32  
    33  func TestTransportMultiplexConnFilter(t *testing.T) {
    34  	mt := newMultiplexTransport(
    35  		emptyNodeInfo(),
    36  		NodeKey{
    37  			PrivKey: ed25519.GenPrivKey(),
    38  		},
    39  	)
    40  	id := mt.nodeKey.ID()
    41  
    42  	MultiplexTransportConnFilters(
    43  		func(_ ConnSet, _ net.Conn, _ []net.IP) error { return nil },
    44  		func(_ ConnSet, _ net.Conn, _ []net.IP) error { return nil },
    45  		func(_ ConnSet, _ net.Conn, _ []net.IP) error {
    46  			return fmt.Errorf("rejected")
    47  		},
    48  	)(mt)
    49  
    50  	addr, err := NewNetAddressString(IDAddressString(id, "127.0.0.1:0"))
    51  	if err != nil {
    52  		t.Fatal(err)
    53  	}
    54  
    55  	if err := mt.Listen(*addr); err != nil {
    56  		t.Fatal(err)
    57  	}
    58  
    59  	errc := make(chan error)
    60  
    61  	go func() {
    62  		addr := NewNetAddress(id, mt.listener.Addr())
    63  
    64  		_, err := addr.Dial()
    65  		if err != nil {
    66  			errc <- err
    67  			return
    68  		}
    69  
    70  		close(errc)
    71  	}()
    72  
    73  	if err := <-errc; err != nil {
    74  		t.Errorf("connection failed: %v", err)
    75  	}
    76  
    77  	_, err = mt.Accept(peerConfig{})
    78  	if err, ok := err.(ErrRejected); ok {
    79  		if !err.IsFiltered() {
    80  			t.Errorf("expected peer to be filtered")
    81  		}
    82  	} else {
    83  		t.Errorf("expected ErrRejected")
    84  	}
    85  }
    86  
    87  func TestTransportMultiplexConnFilterTimeout(t *testing.T) {
    88  	mt := newMultiplexTransport(
    89  		emptyNodeInfo(),
    90  		NodeKey{
    91  			PrivKey: ed25519.GenPrivKey(),
    92  		},
    93  	)
    94  	id := mt.nodeKey.ID()
    95  
    96  	MultiplexTransportFilterTimeout(5 * time.Millisecond)(mt)
    97  	MultiplexTransportConnFilters(
    98  		func(_ ConnSet, _ net.Conn, _ []net.IP) error {
    99  			time.Sleep(10 * time.Millisecond)
   100  			return nil
   101  		},
   102  	)(mt)
   103  
   104  	addr, err := NewNetAddressString(IDAddressString(id, "127.0.0.1:0"))
   105  	if err != nil {
   106  		t.Fatal(err)
   107  	}
   108  
   109  	if err := mt.Listen(*addr); err != nil {
   110  		t.Fatal(err)
   111  	}
   112  
   113  	errc := make(chan error)
   114  
   115  	go func() {
   116  		addr := NewNetAddress(id, mt.listener.Addr())
   117  
   118  		_, err := addr.Dial()
   119  		if err != nil {
   120  			errc <- err
   121  			return
   122  		}
   123  
   124  		close(errc)
   125  	}()
   126  
   127  	if err := <-errc; err != nil {
   128  		t.Errorf("connection failed: %v", err)
   129  	}
   130  
   131  	_, err = mt.Accept(peerConfig{})
   132  	if _, ok := err.(ErrFilterTimeout); !ok {
   133  		t.Errorf("expected ErrFilterTimeout")
   134  	}
   135  }
   136  
   137  func TestTransportMultiplexAcceptMultiple(t *testing.T) {
   138  	mt := testSetupMultiplexTransport(t)
   139  	laddr := NewNetAddress(mt.nodeKey.ID(), mt.listener.Addr())
   140  
   141  	var (
   142  		seed     = rand.New(rand.NewSource(time.Now().UnixNano()))
   143  		nDialers = seed.Intn(64) + 64
   144  		errc     = make(chan error, nDialers)
   145  	)
   146  
   147  	// Setup dialers.
   148  	for i := 0; i < nDialers; i++ {
   149  		go testDialer(*laddr, errc)
   150  	}
   151  
   152  	// Catch connection errors.
   153  	for i := 0; i < nDialers; i++ {
   154  		if err := <-errc; err != nil {
   155  			t.Fatal(err)
   156  		}
   157  	}
   158  
   159  	ps := []Peer{}
   160  
   161  	// Accept all peers.
   162  	for i := 0; i < cap(errc); i++ {
   163  		p, err := mt.Accept(peerConfig{})
   164  		if err != nil {
   165  			t.Fatal(err)
   166  		}
   167  
   168  		if err := p.Start(); err != nil {
   169  			t.Fatal(err)
   170  		}
   171  
   172  		ps = append(ps, p)
   173  	}
   174  
   175  	if have, want := len(ps), cap(errc); have != want {
   176  		t.Errorf("have %v, want %v", have, want)
   177  	}
   178  
   179  	// Stop all peers.
   180  	for _, p := range ps {
   181  		if err := p.Stop(); err != nil {
   182  			t.Fatal(err)
   183  		}
   184  	}
   185  
   186  	if err := mt.Close(); err != nil {
   187  		t.Errorf("close errored: %v", err)
   188  	}
   189  }
   190  
   191  func testDialer(dialAddr NetAddress, errc chan error) {
   192  	var (
   193  		pv     = ed25519.GenPrivKey()
   194  		dialer = newMultiplexTransport(
   195  			testNodeInfo(PubKeyToID(pv.PubKey()), defaultNodeName),
   196  			NodeKey{
   197  				PrivKey: pv,
   198  			},
   199  		)
   200  	)
   201  
   202  	_, err := dialer.Dial(dialAddr, peerConfig{})
   203  	if err != nil {
   204  		errc <- err
   205  		return
   206  	}
   207  
   208  	// Signal that the connection was established.
   209  	errc <- nil
   210  }
   211  
   212  func TestTransportMultiplexAcceptNonBlocking(t *testing.T) {
   213  	mt := testSetupMultiplexTransport(t)
   214  
   215  	var (
   216  		fastNodePV   = ed25519.GenPrivKey()
   217  		fastNodeInfo = testNodeInfo(PubKeyToID(fastNodePV.PubKey()), "fastnode")
   218  		errc         = make(chan error)
   219  		fastc        = make(chan struct{})
   220  		slowc        = make(chan struct{})
   221  	)
   222  
   223  	// Simulate slow Peer.
   224  	go func() {
   225  		addr := NewNetAddress(mt.nodeKey.ID(), mt.listener.Addr())
   226  
   227  		c, err := addr.Dial()
   228  		if err != nil {
   229  			errc <- err
   230  			return
   231  		}
   232  
   233  		close(slowc)
   234  
   235  		select {
   236  		case <-fastc:
   237  			// Fast peer connected.
   238  		case <-time.After(50 * time.Millisecond):
   239  			// We error if the fast peer didn't succeed.
   240  			errc <- fmt.Errorf("Fast peer timed out")
   241  		}
   242  
   243  		sc, err := upgradeSecretConn(c, 20*time.Millisecond, ed25519.GenPrivKey())
   244  		if err != nil {
   245  			errc <- err
   246  			return
   247  		}
   248  
   249  		_, err = handshake(sc, 20*time.Millisecond,
   250  			testNodeInfo(
   251  				PubKeyToID(ed25519.GenPrivKey().PubKey()),
   252  				"slow_peer",
   253  			))
   254  		if err != nil {
   255  			errc <- err
   256  			return
   257  		}
   258  	}()
   259  
   260  	// Simulate fast Peer.
   261  	go func() {
   262  		<-slowc
   263  
   264  		var (
   265  			dialer = newMultiplexTransport(
   266  				fastNodeInfo,
   267  				NodeKey{
   268  					PrivKey: fastNodePV,
   269  				},
   270  			)
   271  		)
   272  		addr := NewNetAddress(mt.nodeKey.ID(), mt.listener.Addr())
   273  
   274  		_, err := dialer.Dial(*addr, peerConfig{})
   275  		if err != nil {
   276  			errc <- err
   277  			return
   278  		}
   279  
   280  		close(errc)
   281  		close(fastc)
   282  	}()
   283  
   284  	if err := <-errc; err != nil {
   285  		t.Errorf("connection failed: %v", err)
   286  	}
   287  
   288  	p, err := mt.Accept(peerConfig{})
   289  	if err != nil {
   290  		t.Fatal(err)
   291  	}
   292  
   293  	if have, want := p.NodeInfo(), fastNodeInfo; !reflect.DeepEqual(have, want) {
   294  		t.Errorf("have %v, want %v", have, want)
   295  	}
   296  }
   297  
   298  func TestTransportMultiplexValidateNodeInfo(t *testing.T) {
   299  	mt := testSetupMultiplexTransport(t)
   300  
   301  	errc := make(chan error)
   302  
   303  	go func() {
   304  		var (
   305  			pv     = ed25519.GenPrivKey()
   306  			dialer = newMultiplexTransport(
   307  				testNodeInfo(PubKeyToID(pv.PubKey()), ""), // Should not be empty
   308  				NodeKey{
   309  					PrivKey: pv,
   310  				},
   311  			)
   312  		)
   313  
   314  		addr := NewNetAddress(mt.nodeKey.ID(), mt.listener.Addr())
   315  
   316  		_, err := dialer.Dial(*addr, peerConfig{})
   317  		if err != nil {
   318  			errc <- err
   319  			return
   320  		}
   321  
   322  		close(errc)
   323  	}()
   324  
   325  	if err := <-errc; err != nil {
   326  		t.Errorf("connection failed: %v", err)
   327  	}
   328  
   329  	_, err := mt.Accept(peerConfig{})
   330  	if err, ok := err.(ErrRejected); ok {
   331  		if !err.IsNodeInfoInvalid() {
   332  			t.Errorf("expected NodeInfo to be invalid")
   333  		}
   334  	} else {
   335  		t.Errorf("expected ErrRejected")
   336  	}
   337  }
   338  
   339  func TestTransportMultiplexRejectMissmatchID(t *testing.T) {
   340  	mt := testSetupMultiplexTransport(t)
   341  
   342  	errc := make(chan error)
   343  
   344  	go func() {
   345  		dialer := newMultiplexTransport(
   346  			testNodeInfo(
   347  				PubKeyToID(ed25519.GenPrivKey().PubKey()), "dialer",
   348  			),
   349  			NodeKey{
   350  				PrivKey: ed25519.GenPrivKey(),
   351  			},
   352  		)
   353  		addr := NewNetAddress(mt.nodeKey.ID(), mt.listener.Addr())
   354  
   355  		_, err := dialer.Dial(*addr, peerConfig{})
   356  		if err != nil {
   357  			errc <- err
   358  			return
   359  		}
   360  
   361  		close(errc)
   362  	}()
   363  
   364  	if err := <-errc; err != nil {
   365  		t.Errorf("connection failed: %v", err)
   366  	}
   367  
   368  	_, err := mt.Accept(peerConfig{})
   369  	if err, ok := err.(ErrRejected); ok {
   370  		if !err.IsAuthFailure() {
   371  			t.Errorf("expected auth failure")
   372  		}
   373  	} else {
   374  		t.Errorf("expected ErrRejected")
   375  	}
   376  }
   377  
   378  func TestTransportMultiplexDialRejectWrongID(t *testing.T) {
   379  	mt := testSetupMultiplexTransport(t)
   380  
   381  	var (
   382  		pv     = ed25519.GenPrivKey()
   383  		dialer = newMultiplexTransport(
   384  			testNodeInfo(PubKeyToID(pv.PubKey()), ""), // Should not be empty
   385  			NodeKey{
   386  				PrivKey: pv,
   387  			},
   388  		)
   389  	)
   390  
   391  	wrongID := PubKeyToID(ed25519.GenPrivKey().PubKey())
   392  	addr := NewNetAddress(wrongID, mt.listener.Addr())
   393  
   394  	_, err := dialer.Dial(*addr, peerConfig{})
   395  	if err != nil {
   396  		t.Logf("connection failed: %v", err)
   397  		if err, ok := err.(ErrRejected); ok {
   398  			if !err.IsAuthFailure() {
   399  				t.Errorf("expected auth failure")
   400  			}
   401  		} else {
   402  			t.Errorf("expected ErrRejected")
   403  		}
   404  	}
   405  }
   406  
   407  func TestTransportMultiplexRejectIncompatible(t *testing.T) {
   408  	mt := testSetupMultiplexTransport(t)
   409  
   410  	errc := make(chan error)
   411  
   412  	go func() {
   413  		var (
   414  			pv     = ed25519.GenPrivKey()
   415  			dialer = newMultiplexTransport(
   416  				testNodeInfoWithNetwork(PubKeyToID(pv.PubKey()), "dialer", "incompatible-network"),
   417  				NodeKey{
   418  					PrivKey: pv,
   419  				},
   420  			)
   421  		)
   422  		addr := NewNetAddress(mt.nodeKey.ID(), mt.listener.Addr())
   423  
   424  		_, err := dialer.Dial(*addr, peerConfig{})
   425  		if err != nil {
   426  			errc <- err
   427  			return
   428  		}
   429  
   430  		close(errc)
   431  	}()
   432  
   433  	_, err := mt.Accept(peerConfig{})
   434  	if err, ok := err.(ErrRejected); ok {
   435  		if !err.IsIncompatible() {
   436  			t.Errorf("expected to reject incompatible")
   437  		}
   438  	} else {
   439  		t.Errorf("expected ErrRejected")
   440  	}
   441  }
   442  
   443  func TestTransportMultiplexRejectSelf(t *testing.T) {
   444  	mt := testSetupMultiplexTransport(t)
   445  
   446  	errc := make(chan error)
   447  
   448  	go func() {
   449  		addr := NewNetAddress(mt.nodeKey.ID(), mt.listener.Addr())
   450  
   451  		_, err := mt.Dial(*addr, peerConfig{})
   452  		if err != nil {
   453  			errc <- err
   454  			return
   455  		}
   456  
   457  		close(errc)
   458  	}()
   459  
   460  	if err := <-errc; err != nil {
   461  		if err, ok := err.(ErrRejected); ok {
   462  			if !err.IsSelf() {
   463  				t.Errorf("expected to reject self, got: %v", err)
   464  			}
   465  		} else {
   466  			t.Errorf("expected ErrRejected")
   467  		}
   468  	} else {
   469  		t.Errorf("expected connection failure")
   470  	}
   471  
   472  	_, err := mt.Accept(peerConfig{})
   473  	if err, ok := err.(ErrRejected); ok {
   474  		if !err.IsSelf() {
   475  			t.Errorf("expected to reject self, got: %v", err)
   476  		}
   477  	} else {
   478  		t.Errorf("expected ErrRejected")
   479  	}
   480  }
   481  
   482  func TestTransportConnDuplicateIPFilter(t *testing.T) {
   483  	filter := ConnDuplicateIPFilter()
   484  
   485  	if err := filter(nil, &testTransportConn{}, nil); err != nil {
   486  		t.Fatal(err)
   487  	}
   488  
   489  	var (
   490  		c  = &testTransportConn{}
   491  		cs = NewConnSet()
   492  	)
   493  
   494  	cs.Set(c, []net.IP{
   495  		{10, 0, 10, 1},
   496  		{10, 0, 10, 2},
   497  		{10, 0, 10, 3},
   498  	})
   499  
   500  	if err := filter(cs, c, []net.IP{
   501  		{10, 0, 10, 2},
   502  	}); err == nil {
   503  		t.Errorf("expected Peer to be rejected as duplicate")
   504  	}
   505  }
   506  
   507  func TestTransportHandshake(t *testing.T) {
   508  	ln, err := net.Listen("tcp", "127.0.0.1:0")
   509  	if err != nil {
   510  		t.Fatal(err)
   511  	}
   512  
   513  	var (
   514  		peerPV       = ed25519.GenPrivKey()
   515  		peerNodeInfo = testNodeInfo(PubKeyToID(peerPV.PubKey()), defaultNodeName)
   516  	)
   517  
   518  	go func() {
   519  		c, err := net.Dial(ln.Addr().Network(), ln.Addr().String())
   520  		if err != nil {
   521  			t.Error(err)
   522  			return
   523  		}
   524  
   525  		go func(c net.Conn) {
   526  			_, err := cdc.MarshalBinaryLengthPrefixedWriter(c, peerNodeInfo.(DefaultNodeInfo))
   527  			if err != nil {
   528  				t.Error(err)
   529  			}
   530  		}(c)
   531  		go func(c net.Conn) {
   532  			var ni DefaultNodeInfo
   533  
   534  			_, err := cdc.UnmarshalBinaryLengthPrefixedReader(
   535  				c,
   536  				&ni,
   537  				int64(MaxNodeInfoSize()),
   538  			)
   539  			if err != nil {
   540  				t.Error(err)
   541  			}
   542  		}(c)
   543  	}()
   544  
   545  	c, err := ln.Accept()
   546  	if err != nil {
   547  		t.Fatal(err)
   548  	}
   549  
   550  	ni, err := handshake(c, 20*time.Millisecond, emptyNodeInfo())
   551  	if err != nil {
   552  		t.Fatal(err)
   553  	}
   554  
   555  	if have, want := ni, peerNodeInfo; !reflect.DeepEqual(have, want) {
   556  		t.Errorf("have %v, want %v", have, want)
   557  	}
   558  }
   559  
   560  // create listener
   561  func testSetupMultiplexTransport(t *testing.T) *MultiplexTransport {
   562  	var (
   563  		pv = ed25519.GenPrivKey()
   564  		id = PubKeyToID(pv.PubKey())
   565  		mt = newMultiplexTransport(
   566  			testNodeInfo(
   567  				id, "transport",
   568  			),
   569  			NodeKey{
   570  				PrivKey: pv,
   571  			},
   572  		)
   573  	)
   574  
   575  	addr, err := NewNetAddressString(IDAddressString(id, "127.0.0.1:0"))
   576  	if err != nil {
   577  		t.Fatal(err)
   578  	}
   579  
   580  	if err := mt.Listen(*addr); err != nil {
   581  		t.Fatal(err)
   582  	}
   583  
   584  	return mt
   585  }
   586  
   587  type testTransportAddr struct{}
   588  
   589  func (a *testTransportAddr) Network() string { return "tcp" }
   590  func (a *testTransportAddr) String() string  { return "test.local:1234" }
   591  
   592  type testTransportConn struct{}
   593  
   594  func (c *testTransportConn) Close() error {
   595  	return fmt.Errorf("Close() not implemented")
   596  }
   597  
   598  func (c *testTransportConn) LocalAddr() net.Addr {
   599  	return &testTransportAddr{}
   600  }
   601  
   602  func (c *testTransportConn) RemoteAddr() net.Addr {
   603  	return &testTransportAddr{}
   604  }
   605  
   606  func (c *testTransportConn) Read(_ []byte) (int, error) {
   607  	return -1, fmt.Errorf("Read() not implemented")
   608  }
   609  
   610  func (c *testTransportConn) SetDeadline(_ time.Time) error {
   611  	return fmt.Errorf("SetDeadline() not implemented")
   612  }
   613  
   614  func (c *testTransportConn) SetReadDeadline(_ time.Time) error {
   615  	return fmt.Errorf("SetReadDeadline() not implemented")
   616  }
   617  
   618  func (c *testTransportConn) SetWriteDeadline(_ time.Time) error {
   619  	return fmt.Errorf("SetWriteDeadline() not implemented")
   620  }
   621  
   622  func (c *testTransportConn) Write(_ []byte) (int, error) {
   623  	return -1, fmt.Errorf("Write() not implemented")
   624  }