github.com/pure-x-eth/consensus_tm@v0.0.0-20230502163723-e3c2ff987250/p2p/transport_test.go (about)

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