github.com/okex/exchain@v1.8.0/libs/tendermint/p2p/conn/connection_test.go (about)

     1  package conn
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"math"
     7  	"math/big"
     8  	"math/rand"
     9  	"net"
    10  	"os"
    11  	"testing"
    12  	"time"
    13  
    14  	ethcmn "github.com/ethereum/go-ethereum/common"
    15  
    16  	"github.com/fortytw2/leaktest"
    17  	"github.com/stretchr/testify/assert"
    18  	"github.com/stretchr/testify/require"
    19  
    20  	amino "github.com/tendermint/go-amino"
    21  
    22  	"github.com/okex/exchain/libs/tendermint/libs/log"
    23  )
    24  
    25  const maxPingPongPacketSize = 1024 // bytes
    26  
    27  func createTestMConnection(conn net.Conn) *MConnection {
    28  	onReceive := func(chID byte, msgBytes []byte) {
    29  	}
    30  	onError := func(r interface{}) {
    31  	}
    32  	c := createMConnectionWithCallbacks(conn, onReceive, onError)
    33  	c.SetLogger(log.TestingLogger())
    34  	return c
    35  }
    36  
    37  func createMConnectionWithCallbacks(
    38  	conn net.Conn,
    39  	onReceive func(chID byte, msgBytes []byte),
    40  	onError func(r interface{}),
    41  ) *MConnection {
    42  	cfg := DefaultMConnConfig()
    43  	cfg.PingInterval = 90 * time.Millisecond
    44  	cfg.PongTimeout = 45 * time.Millisecond
    45  	chDescs := []*ChannelDescriptor{{ID: 0x01, Priority: 1, SendQueueCapacity: 1}}
    46  	c := NewMConnectionWithConfig(conn, chDescs, onReceive, onError, cfg)
    47  	c.SetLogger(log.TestingLogger())
    48  	return c
    49  }
    50  
    51  func TestMConnectionSendFlushStop(t *testing.T) {
    52  	server, client := NetPipe()
    53  	defer server.Close() // nolint: errcheck
    54  	defer client.Close() // nolint: errcheck
    55  
    56  	clientConn := createTestMConnection(client)
    57  	err := clientConn.Start()
    58  	require.Nil(t, err)
    59  	defer clientConn.Stop()
    60  
    61  	msg := []byte("abc")
    62  	assert.True(t, clientConn.Send(0x01, msg))
    63  
    64  	aminoMsgLength := 14
    65  
    66  	// start the reader in a new routine, so we can flush
    67  	errCh := make(chan error)
    68  	go func() {
    69  		msgB := make([]byte, aminoMsgLength)
    70  		_, err := server.Read(msgB)
    71  		if err != nil {
    72  			t.Error(err)
    73  			return
    74  		}
    75  		errCh <- err
    76  	}()
    77  
    78  	// stop the conn - it should flush all conns
    79  	clientConn.FlushStop()
    80  
    81  	timer := time.NewTimer(3 * time.Second)
    82  	select {
    83  	case <-errCh:
    84  	case <-timer.C:
    85  		t.Error("timed out waiting for msgs to be read")
    86  	}
    87  }
    88  
    89  func TestMConnectionSend(t *testing.T) {
    90  	server, client := NetPipe()
    91  	defer server.Close() // nolint: errcheck
    92  	defer client.Close() // nolint: errcheck
    93  
    94  	mconn := createTestMConnection(client)
    95  	err := mconn.Start()
    96  	require.Nil(t, err)
    97  	defer mconn.Stop()
    98  
    99  	msg := []byte("Ant-Man")
   100  	assert.True(t, mconn.Send(0x01, msg))
   101  	// Note: subsequent Send/TrySend calls could pass because we are reading from
   102  	// the send queue in a separate goroutine.
   103  	_, err = server.Read(make([]byte, len(msg)))
   104  	if err != nil {
   105  		t.Error(err)
   106  	}
   107  	assert.True(t, mconn.CanSend(0x01))
   108  
   109  	msg = []byte("Spider-Man")
   110  	assert.True(t, mconn.TrySend(0x01, msg))
   111  	_, err = server.Read(make([]byte, len(msg)))
   112  	if err != nil {
   113  		t.Error(err)
   114  	}
   115  
   116  	assert.False(t, mconn.CanSend(0x05), "CanSend should return false because channel is unknown")
   117  	assert.False(t, mconn.Send(0x05, []byte("Absorbing Man")), "Send should return false because channel is unknown")
   118  }
   119  
   120  func TestMConnectionReceive(t *testing.T) {
   121  	server, client := NetPipe()
   122  	defer server.Close() // nolint: errcheck
   123  	defer client.Close() // nolint: errcheck
   124  
   125  	receivedCh := make(chan []byte)
   126  	errorsCh := make(chan interface{})
   127  	onReceive := func(chID byte, msgBytes []byte) {
   128  		receivedCh <- msgBytes
   129  	}
   130  	onError := func(r interface{}) {
   131  		errorsCh <- r
   132  	}
   133  	mconn1 := createMConnectionWithCallbacks(client, onReceive, onError)
   134  	err := mconn1.Start()
   135  	require.Nil(t, err)
   136  	defer mconn1.Stop()
   137  
   138  	mconn2 := createTestMConnection(server)
   139  	err = mconn2.Start()
   140  	require.Nil(t, err)
   141  	defer mconn2.Stop()
   142  
   143  	msg := []byte("Cyclops")
   144  	assert.True(t, mconn2.Send(0x01, msg))
   145  
   146  	select {
   147  	case receivedBytes := <-receivedCh:
   148  		assert.Equal(t, msg, receivedBytes)
   149  	case err := <-errorsCh:
   150  		t.Fatalf("Expected %s, got %+v", msg, err)
   151  	case <-time.After(500 * time.Millisecond):
   152  		t.Fatalf("Did not receive %s message in 500ms", msg)
   153  	}
   154  }
   155  
   156  func TestMConnectionStatus(t *testing.T) {
   157  	server, client := NetPipe()
   158  	defer server.Close() // nolint: errcheck
   159  	defer client.Close() // nolint: errcheck
   160  
   161  	mconn := createTestMConnection(client)
   162  	err := mconn.Start()
   163  	require.Nil(t, err)
   164  	defer mconn.Stop()
   165  
   166  	status := mconn.Status()
   167  	assert.NotNil(t, status)
   168  	assert.Zero(t, status.Channels[0].SendQueueSize)
   169  }
   170  
   171  func TestMConnectionPongTimeoutResultsInError(t *testing.T) {
   172  	server, client := net.Pipe()
   173  	defer server.Close()
   174  	defer client.Close()
   175  
   176  	receivedCh := make(chan []byte)
   177  	errorsCh := make(chan interface{})
   178  	onReceive := func(chID byte, msgBytes []byte) {
   179  		receivedCh <- msgBytes
   180  	}
   181  	onError := func(r interface{}) {
   182  		errorsCh <- r
   183  	}
   184  	mconn := createMConnectionWithCallbacks(client, onReceive, onError)
   185  	err := mconn.Start()
   186  	require.Nil(t, err)
   187  	defer mconn.Stop()
   188  
   189  	serverGotPing := make(chan struct{})
   190  	go func() {
   191  		// read ping
   192  		var pkt PacketPing
   193  		_, err = cdc.UnmarshalBinaryLengthPrefixedReader(server, &pkt, maxPingPongPacketSize)
   194  		assert.Nil(t, err)
   195  		serverGotPing <- struct{}{}
   196  	}()
   197  	<-serverGotPing
   198  
   199  	pongTimerExpired := mconn.config.PongTimeout + 20*time.Millisecond
   200  	select {
   201  	case msgBytes := <-receivedCh:
   202  		t.Fatalf("Expected error, but got %v", msgBytes)
   203  	case err := <-errorsCh:
   204  		assert.NotNil(t, err)
   205  	case <-time.After(pongTimerExpired):
   206  		t.Fatalf("Expected to receive error after %v", pongTimerExpired)
   207  	}
   208  }
   209  
   210  func TestMConnectionMultiplePongsInTheBeginning(t *testing.T) {
   211  	server, client := net.Pipe()
   212  	defer server.Close()
   213  	defer client.Close()
   214  
   215  	receivedCh := make(chan []byte)
   216  	errorsCh := make(chan interface{})
   217  	onReceive := func(chID byte, msgBytes []byte) {
   218  		receivedCh <- msgBytes
   219  	}
   220  	onError := func(r interface{}) {
   221  		errorsCh <- r
   222  	}
   223  	mconn := createMConnectionWithCallbacks(client, onReceive, onError)
   224  	err := mconn.Start()
   225  	require.Nil(t, err)
   226  	defer mconn.Stop()
   227  
   228  	// sending 3 pongs in a row (abuse)
   229  	_, err = server.Write(cdc.MustMarshalBinaryLengthPrefixed(PacketPong{}))
   230  	require.Nil(t, err)
   231  	_, err = server.Write(cdc.MustMarshalBinaryLengthPrefixed(PacketPong{}))
   232  	require.Nil(t, err)
   233  	_, err = server.Write(cdc.MustMarshalBinaryLengthPrefixed(PacketPong{}))
   234  	require.Nil(t, err)
   235  
   236  	serverGotPing := make(chan struct{})
   237  	go func() {
   238  		// read ping (one byte)
   239  		var (
   240  			packet Packet
   241  			err    error
   242  		)
   243  		_, err = cdc.UnmarshalBinaryLengthPrefixedReader(server, &packet, maxPingPongPacketSize)
   244  		require.Nil(t, err)
   245  		serverGotPing <- struct{}{}
   246  		// respond with pong
   247  		_, err = server.Write(cdc.MustMarshalBinaryLengthPrefixed(PacketPong{}))
   248  		require.Nil(t, err)
   249  	}()
   250  	<-serverGotPing
   251  
   252  	pongTimerExpired := mconn.config.PongTimeout + 20*time.Millisecond
   253  	select {
   254  	case msgBytes := <-receivedCh:
   255  		t.Fatalf("Expected no data, but got %v", msgBytes)
   256  	case err := <-errorsCh:
   257  		t.Fatalf("Expected no error, but got %v", err)
   258  	case <-time.After(pongTimerExpired):
   259  		assert.True(t, mconn.IsRunning())
   260  	}
   261  }
   262  
   263  func TestMConnectionMultiplePings(t *testing.T) {
   264  	server, client := net.Pipe()
   265  	defer server.Close()
   266  	defer client.Close()
   267  
   268  	receivedCh := make(chan []byte)
   269  	errorsCh := make(chan interface{})
   270  	onReceive := func(chID byte, msgBytes []byte) {
   271  		receivedCh <- msgBytes
   272  	}
   273  	onError := func(r interface{}) {
   274  		errorsCh <- r
   275  	}
   276  	mconn := createMConnectionWithCallbacks(client, onReceive, onError)
   277  	err := mconn.Start()
   278  	require.Nil(t, err)
   279  	defer mconn.Stop()
   280  
   281  	// sending 3 pings in a row (abuse)
   282  	// see https://github.com/tendermint/tendermint/issues/1190
   283  	_, err = server.Write(cdc.MustMarshalBinaryLengthPrefixed(PacketPing{}))
   284  	require.Nil(t, err)
   285  	var pkt PacketPong
   286  	_, err = cdc.UnmarshalBinaryLengthPrefixedReader(server, &pkt, maxPingPongPacketSize)
   287  	require.Nil(t, err)
   288  	_, err = server.Write(cdc.MustMarshalBinaryLengthPrefixed(PacketPing{}))
   289  	require.Nil(t, err)
   290  	_, err = cdc.UnmarshalBinaryLengthPrefixedReader(server, &pkt, maxPingPongPacketSize)
   291  	require.Nil(t, err)
   292  	_, err = server.Write(cdc.MustMarshalBinaryLengthPrefixed(PacketPing{}))
   293  	require.Nil(t, err)
   294  	_, err = cdc.UnmarshalBinaryLengthPrefixedReader(server, &pkt, maxPingPongPacketSize)
   295  	require.Nil(t, err)
   296  
   297  	assert.True(t, mconn.IsRunning())
   298  }
   299  
   300  func TestMConnectionPingPongs(t *testing.T) {
   301  	// check that we are not leaking any go-routines
   302  	defer leaktest.CheckTimeout(t, 10*time.Second)()
   303  
   304  	server, client := net.Pipe()
   305  
   306  	defer server.Close()
   307  	defer client.Close()
   308  
   309  	receivedCh := make(chan []byte)
   310  	errorsCh := make(chan interface{})
   311  	onReceive := func(chID byte, msgBytes []byte) {
   312  		receivedCh <- msgBytes
   313  	}
   314  	onError := func(r interface{}) {
   315  		errorsCh <- r
   316  	}
   317  	mconn := createMConnectionWithCallbacks(client, onReceive, onError)
   318  	err := mconn.Start()
   319  	require.Nil(t, err)
   320  	defer mconn.Stop()
   321  
   322  	serverGotPing := make(chan struct{})
   323  	go func() {
   324  		// read ping
   325  		var pkt PacketPing
   326  		_, err = cdc.UnmarshalBinaryLengthPrefixedReader(server, &pkt, maxPingPongPacketSize)
   327  		require.Nil(t, err)
   328  		serverGotPing <- struct{}{}
   329  		// respond with pong
   330  		_, err = server.Write(cdc.MustMarshalBinaryLengthPrefixed(PacketPong{}))
   331  		require.Nil(t, err)
   332  
   333  		time.Sleep(mconn.config.PingInterval)
   334  
   335  		// read ping
   336  		_, err = cdc.UnmarshalBinaryLengthPrefixedReader(server, &pkt, maxPingPongPacketSize)
   337  		require.Nil(t, err)
   338  		// respond with pong
   339  		_, err = server.Write(cdc.MustMarshalBinaryLengthPrefixed(PacketPong{}))
   340  		require.Nil(t, err)
   341  	}()
   342  	<-serverGotPing
   343  
   344  	pongTimerExpired := (mconn.config.PongTimeout + 20*time.Millisecond) * 2
   345  	select {
   346  	case msgBytes := <-receivedCh:
   347  		t.Fatalf("Expected no data, but got %v", msgBytes)
   348  	case err := <-errorsCh:
   349  		t.Fatalf("Expected no error, but got %v", err)
   350  	case <-time.After(2 * pongTimerExpired):
   351  		assert.True(t, mconn.IsRunning())
   352  	}
   353  }
   354  
   355  func TestMConnectionStopsAndReturnsError(t *testing.T) {
   356  	server, client := NetPipe()
   357  	defer server.Close() // nolint: errcheck
   358  	defer client.Close() // nolint: errcheck
   359  
   360  	receivedCh := make(chan []byte)
   361  	errorsCh := make(chan interface{})
   362  	onReceive := func(chID byte, msgBytes []byte) {
   363  		receivedCh <- msgBytes
   364  	}
   365  	onError := func(r interface{}) {
   366  		errorsCh <- r
   367  	}
   368  	mconn := createMConnectionWithCallbacks(client, onReceive, onError)
   369  	err := mconn.Start()
   370  	require.Nil(t, err)
   371  	defer mconn.Stop()
   372  
   373  	if err := client.Close(); err != nil {
   374  		t.Error(err)
   375  	}
   376  
   377  	select {
   378  	case receivedBytes := <-receivedCh:
   379  		t.Fatalf("Expected error, got %v", receivedBytes)
   380  	case err := <-errorsCh:
   381  		assert.NotNil(t, err)
   382  		assert.False(t, mconn.IsRunning())
   383  	case <-time.After(500 * time.Millisecond):
   384  		t.Fatal("Did not receive error in 500ms")
   385  	}
   386  }
   387  
   388  func newClientAndServerConnsForReadErrors(t *testing.T, chOnErr chan struct{}) (*MConnection, *MConnection) {
   389  	server, client := NetPipe()
   390  
   391  	onReceive := func(chID byte, msgBytes []byte) {}
   392  	onError := func(r interface{}) {}
   393  
   394  	// create client conn with two channels
   395  	chDescs := []*ChannelDescriptor{
   396  		{ID: 0x01, Priority: 1, SendQueueCapacity: 1},
   397  		{ID: 0x02, Priority: 1, SendQueueCapacity: 1},
   398  	}
   399  	mconnClient := NewMConnection(client, chDescs, onReceive, onError)
   400  	mconnClient.SetLogger(log.TestingLogger().With("module", "client"))
   401  	err := mconnClient.Start()
   402  	require.Nil(t, err)
   403  
   404  	// create server conn with 1 channel
   405  	// it fires on chOnErr when there's an error
   406  	serverLogger := log.TestingLogger().With("module", "server")
   407  	onError = func(r interface{}) {
   408  		chOnErr <- struct{}{}
   409  	}
   410  	mconnServer := createMConnectionWithCallbacks(server, onReceive, onError)
   411  	mconnServer.SetLogger(serverLogger)
   412  	err = mconnServer.Start()
   413  	require.Nil(t, err)
   414  	return mconnClient, mconnServer
   415  }
   416  
   417  func expectSend(ch chan struct{}) bool {
   418  	after := time.After(time.Second * 5)
   419  	select {
   420  	case <-ch:
   421  		return true
   422  	case <-after:
   423  		return false
   424  	}
   425  }
   426  
   427  func TestMConnectionReadErrorBadEncoding(t *testing.T) {
   428  	chOnErr := make(chan struct{})
   429  	mconnClient, mconnServer := newClientAndServerConnsForReadErrors(t, chOnErr)
   430  	defer mconnClient.Stop()
   431  	defer mconnServer.Stop()
   432  
   433  	client := mconnClient.conn
   434  
   435  	// send badly encoded msgPacket
   436  	bz := cdc.MustMarshalBinaryLengthPrefixed(PacketMsg{})
   437  	bz[4] += 0x01 // Invalid prefix bytes.
   438  
   439  	// Write it.
   440  	_, err := client.Write(bz)
   441  	assert.Nil(t, err)
   442  	assert.True(t, expectSend(chOnErr), "badly encoded msgPacket")
   443  }
   444  
   445  func TestMConnectionReadErrorUnknownChannel(t *testing.T) {
   446  	chOnErr := make(chan struct{})
   447  	mconnClient, mconnServer := newClientAndServerConnsForReadErrors(t, chOnErr)
   448  	defer mconnClient.Stop()
   449  	defer mconnServer.Stop()
   450  
   451  	msg := []byte("Ant-Man")
   452  
   453  	// fail to send msg on channel unknown by client
   454  	assert.False(t, mconnClient.Send(0x03, msg))
   455  
   456  	// send msg on channel unknown by the server.
   457  	// should cause an error
   458  	assert.True(t, mconnClient.Send(0x02, msg))
   459  	assert.True(t, expectSend(chOnErr), "unknown channel")
   460  }
   461  
   462  func TestMConnectionReadErrorLongMessage(t *testing.T) {
   463  	chOnErr := make(chan struct{})
   464  	chOnRcv := make(chan struct{})
   465  
   466  	mconnClient, mconnServer := newClientAndServerConnsForReadErrors(t, chOnErr)
   467  	defer mconnClient.Stop()
   468  	defer mconnServer.Stop()
   469  
   470  	mconnServer.onReceive = func(chID byte, msgBytes []byte) {
   471  		chOnRcv <- struct{}{}
   472  	}
   473  
   474  	client := mconnClient.conn
   475  
   476  	// send msg thats just right
   477  	var err error
   478  	var buf = new(bytes.Buffer)
   479  	var packet = PacketMsg{
   480  		ChannelID: 0x01,
   481  		EOF:       1,
   482  		Bytes:     make([]byte, mconnClient.config.MaxPacketMsgPayloadSize),
   483  	}
   484  	_, err = cdc.MarshalBinaryLengthPrefixedWriter(buf, packet)
   485  	assert.Nil(t, err)
   486  	_, err = client.Write(buf.Bytes())
   487  	assert.Nil(t, err)
   488  	assert.True(t, expectSend(chOnRcv), "msg just right")
   489  
   490  	// send msg thats too long
   491  	buf = new(bytes.Buffer)
   492  	packet = PacketMsg{
   493  		ChannelID: 0x01,
   494  		EOF:       1,
   495  		Bytes:     make([]byte, mconnClient.config.MaxPacketMsgPayloadSize+100),
   496  	}
   497  	_, err = cdc.MarshalBinaryLengthPrefixedWriter(buf, packet)
   498  	assert.Nil(t, err)
   499  	_, err = client.Write(buf.Bytes())
   500  	assert.NotNil(t, err)
   501  	assert.True(t, expectSend(chOnErr), "msg too long")
   502  }
   503  
   504  func TestMConnectionReadErrorUnknownMsgType(t *testing.T) {
   505  	chOnErr := make(chan struct{})
   506  	mconnClient, mconnServer := newClientAndServerConnsForReadErrors(t, chOnErr)
   507  	defer mconnClient.Stop()
   508  	defer mconnServer.Stop()
   509  
   510  	// send msg with unknown msg type
   511  	err := amino.EncodeUvarint(mconnClient.conn, 4)
   512  	assert.Nil(t, err)
   513  	_, err = mconnClient.conn.Write([]byte{0xFF, 0xFF, 0xFF, 0xFF})
   514  	assert.Nil(t, err)
   515  	assert.True(t, expectSend(chOnErr), "unknown msg type")
   516  }
   517  
   518  func TestMConnectionTrySend(t *testing.T) {
   519  	server, client := NetPipe()
   520  	defer server.Close()
   521  	defer client.Close()
   522  
   523  	mconn := createTestMConnection(client)
   524  	err := mconn.Start()
   525  	require.Nil(t, err)
   526  	defer mconn.Stop()
   527  
   528  	msg := []byte("Semicolon-Woman")
   529  	resultCh := make(chan string, 2)
   530  	assert.True(t, mconn.TrySend(0x01, msg))
   531  	server.Read(make([]byte, len(msg)))
   532  	assert.True(t, mconn.CanSend(0x01))
   533  	assert.True(t, mconn.TrySend(0x01, msg))
   534  	assert.False(t, mconn.CanSend(0x01))
   535  	go func() {
   536  		mconn.TrySend(0x01, msg)
   537  		resultCh <- "TrySend"
   538  	}()
   539  	assert.False(t, mconn.CanSend(0x01))
   540  	assert.False(t, mconn.TrySend(0x01, msg))
   541  	assert.Equal(t, "TrySend", <-resultCh)
   542  }
   543  
   544  func TestPacketAmino(t *testing.T) {
   545  
   546  	packets := []Packet{
   547  		PacketPing{},
   548  		PacketPong{},
   549  		PacketMsg{},
   550  		PacketMsg{0, 0, nil},
   551  		PacketMsg{0, 0, []byte{}},
   552  		PacketMsg{225, 225, []byte{}},
   553  		PacketMsg{0x7f, 45, []byte{0x12, 0x34, 0x56, 0x78}},
   554  		PacketMsg{math.MaxUint8, math.MaxUint8, []byte{0x12, 0x34, 0x56, 0x78}},
   555  	}
   556  
   557  	for _, packet := range packets {
   558  		bz, err := cdc.MarshalBinaryLengthPrefixed(packet)
   559  		require.Nil(t, err)
   560  
   561  		nbz, err := cdc.MarshalBinaryLengthPrefixedWithRegisteredMarshaller(packet)
   562  		require.NoError(t, err)
   563  		require.EqualValues(t, bz, nbz)
   564  
   565  		packet = nil
   566  		err = cdc.UnmarshalBinaryLengthPrefixed(bz, &packet)
   567  		require.NoError(t, err)
   568  
   569  		v, err := cdc.UnmarshalBinaryLengthPrefixedWithRegisteredUbmarshaller(bz, &packet)
   570  		require.NoError(t, err)
   571  		newPacket, ok := v.(Packet)
   572  		require.True(t, ok)
   573  
   574  		var buf bytes.Buffer
   575  		buf.Write(bz)
   576  		newPacket2, n, err := unmarshalPacketFromAminoReader(&buf, int64(buf.Len()), nil)
   577  		require.NoError(t, err)
   578  		require.EqualValues(t, len(bz), n)
   579  
   580  		require.EqualValues(t, packet, newPacket)
   581  		require.EqualValues(t, packet, newPacket2)
   582  	}
   583  }
   584  
   585  func BenchmarkPacketAmino(b *testing.B) {
   586  	hash := ethcmn.BigToHash(big.NewInt(0x12345678))
   587  	buf := bytes.Buffer{}
   588  	for i := 0; i < 10; i++ {
   589  		buf.Write(hash.Bytes())
   590  	}
   591  	msg := PacketMsg{0x7f, 45, buf.Bytes()}
   592  	bz, err := cdc.MarshalBinaryLengthPrefixed(msg)
   593  	require.NoError(b, err)
   594  	b.ResetTimer()
   595  
   596  	b.Run("ping-amino-marshal", func(b *testing.B) {
   597  		b.ReportAllocs()
   598  		for i := 0; i < b.N; i++ {
   599  			var packet Packet
   600  			packet = PacketPing{}
   601  			_, _ = cdc.MarshalBinaryLengthPrefixed(packet)
   602  		}
   603  	})
   604  	b.Run("ping-amino-marshaller", func(b *testing.B) {
   605  		b.ReportAllocs()
   606  		for i := 0; i < b.N; i++ {
   607  			var packet Packet
   608  			packet = PacketPing{}
   609  			_, _ = cdc.MarshalBinaryLengthPrefixedWithRegisteredMarshaller(packet)
   610  		}
   611  	})
   612  	b.Run("msg-amino-marshal", func(b *testing.B) {
   613  		b.ReportAllocs()
   614  		for i := 0; i < b.N; i++ {
   615  			var packet Packet
   616  			packet = PacketMsg{32, 45, []byte{0x12, 0x34, 0x56, 0x78}}
   617  			_, _ = cdc.MarshalBinaryLengthPrefixed(packet)
   618  		}
   619  	})
   620  	b.Run("msg-amino-marshaller", func(b *testing.B) {
   621  		b.ReportAllocs()
   622  		for i := 0; i < b.N; i++ {
   623  			var packet Packet
   624  			packet = PacketMsg{32, 45, []byte{0x12, 0x34, 0x56, 0x78}}
   625  			_, _ = cdc.MarshalBinaryLengthPrefixedWithRegisteredMarshaller(packet)
   626  		}
   627  	})
   628  	b.Run("msg-amino-unmarshal", func(b *testing.B) {
   629  		b.ReportAllocs()
   630  		for i := 0; i < b.N; i++ {
   631  			var packet Packet
   632  			var buf = bytes.NewBuffer(bz)
   633  			_, err = cdc.UnmarshalBinaryLengthPrefixedReader(buf, &packet, int64(buf.Len()))
   634  			if err != nil {
   635  				b.Fatal(err)
   636  			}
   637  		}
   638  	})
   639  	b.Run("msg-amino-unmarshaler", func(b *testing.B) {
   640  		b.ReportAllocs()
   641  		for i := 0; i < b.N; i++ {
   642  			var packet Packet
   643  			var buf = bytes.NewBuffer(bz)
   644  			packet, _, err = unmarshalPacketFromAminoReader(buf, int64(buf.Len()), nil)
   645  			if err != nil {
   646  				b.Fatal(err)
   647  			}
   648  			_ = packet
   649  		}
   650  	})
   651  }
   652  
   653  func TestBytesStringer(t *testing.T) {
   654  	var testData = []byte("test data !!!")
   655  	expect := fmt.Sprintf("%X", testData)
   656  	var testStringer = bytesHexStringer(testData)
   657  	actual := testStringer.String()
   658  	require.EqualValues(t, expect, actual)
   659  	actual = fmt.Sprintf("%s", testStringer)
   660  	require.EqualValues(t, expect, actual)
   661  }
   662  
   663  func TestPacketMsgAmino(t *testing.T) {
   664  	var longBytes = make([]byte, 1024)
   665  	rand.Read(longBytes)
   666  
   667  	testCases := []PacketMsg{
   668  		{},
   669  		{
   670  			ChannelID: 12,
   671  			EOF:       25,
   672  		},
   673  		{
   674  			ChannelID: math.MaxInt8,
   675  			EOF:       math.MaxInt8,
   676  			Bytes:     []byte("Bytes"),
   677  		},
   678  		{
   679  			Bytes: []byte{},
   680  		},
   681  		{
   682  			Bytes: longBytes,
   683  		},
   684  	}
   685  	for _, msg := range testCases {
   686  		expectData, err := cdc.MarshalBinaryBare(msg)
   687  		require.NoError(t, err)
   688  
   689  		actualData, err := cdc.MarshalBinaryBareWithRegisteredMarshaller(msg)
   690  		require.NoError(t, err)
   691  
   692  		require.EqualValues(t, expectData, actualData)
   693  		actualData, err = msg.MarshalToAmino(cdc)
   694  		if actualData == nil {
   695  			actualData = []byte{}
   696  		}
   697  		require.EqualValues(t, expectData[4:], actualData)
   698  
   699  		require.Equal(t, len(actualData), msg.AminoSize(cdc))
   700  
   701  		actualData, err = cdc.MarshalBinaryWithSizer(msg, false)
   702  		require.EqualValues(t, expectData, actualData)
   703  		require.Equal(t, getPacketMsgAminoTypePrefix(), actualData[0:4])
   704  
   705  		expectLenPrefixData, err := cdc.MarshalBinaryLengthPrefixed(msg)
   706  		require.NoError(t, err)
   707  		actualLenPrefixData, err := cdc.MarshalBinaryWithSizer(msg, true)
   708  		require.EqualValues(t, expectLenPrefixData, actualLenPrefixData)
   709  
   710  		var expectValue PacketMsg
   711  		err = cdc.UnmarshalBinaryBare(expectData, &expectValue)
   712  		require.NoError(t, err)
   713  
   714  		var actulaValue = &PacketMsg{}
   715  		tmp, err := cdc.UnmarshalBinaryBareWithRegisteredUnmarshaller(expectData, actulaValue)
   716  		require.NoError(t, err)
   717  		_, ok := tmp.(*PacketMsg)
   718  		require.True(t, ok)
   719  		actulaValue = tmp.(*PacketMsg)
   720  
   721  		require.EqualValues(t, expectValue, *actulaValue)
   722  		err = actulaValue.UnmarshalFromAmino(cdc, expectData[4:])
   723  		require.NoError(t, err)
   724  		require.EqualValues(t, expectValue, *actulaValue)
   725  
   726  		actulaValue = &PacketMsg{}
   727  		err = cdc.UnmarshalBinaryLengthPrefixed(actualLenPrefixData, actulaValue)
   728  		require.NoError(t, err)
   729  		require.EqualValues(t, expectValue, *actulaValue)
   730  	}
   731  }
   732  
   733  func Benchmark(b *testing.B) {
   734  	var longBytes = make([]byte, 1024)
   735  	rand.Read(longBytes)
   736  
   737  	testCases := []PacketMsg{
   738  		{},
   739  		{
   740  			ChannelID: 12,
   741  			EOF:       25,
   742  		},
   743  		{
   744  			ChannelID: math.MaxInt8,
   745  			EOF:       math.MaxInt8,
   746  			Bytes:     []byte("Bytes"),
   747  		},
   748  		{
   749  			Bytes: []byte{},
   750  		},
   751  		{
   752  			Bytes: longBytes,
   753  		},
   754  	}
   755  
   756  	b.Run("amino", func(b *testing.B) {
   757  		b.ReportAllocs()
   758  		for i := 0; i < b.N; i++ {
   759  			for _, msg := range testCases {
   760  				_, err := cdc.MarshalBinaryLengthPrefixedWithRegisteredMarshaller(&msg)
   761  				if err != nil {
   762  					b.Fatal(err)
   763  				}
   764  			}
   765  		}
   766  	})
   767  	b.Run("sizer", func(b *testing.B) {
   768  		b.ReportAllocs()
   769  		for i := 0; i < b.N; i++ {
   770  			for _, msg := range testCases {
   771  				_, err := cdc.MarshalBinaryWithSizer(&msg, true)
   772  				if err != nil {
   773  					b.Fatal(err)
   774  				}
   775  			}
   776  		}
   777  	})
   778  }
   779  
   780  func BenchmarkMConnectionLogSendData(b *testing.B) {
   781  	c := new(MConnection)
   782  	chID := byte(10)
   783  	msgBytes := []byte("Hello World!")
   784  
   785  	logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "benchmark")
   786  	var options []log.Option
   787  	options = append(options, log.AllowInfoWith("module", "benchmark"))
   788  	logger = log.NewFilter(logger, options...)
   789  
   790  	c.Logger = logger
   791  	b.ResetTimer()
   792  
   793  	b.Run("pool", func(b *testing.B) {
   794  		b.ReportAllocs()
   795  		for i := 0; i < b.N; i++ {
   796  			c.logSendData("Send", chID, msgBytes)
   797  		}
   798  	})
   799  
   800  	b.Run("logger", func(b *testing.B) {
   801  		b.ReportAllocs()
   802  		for i := 0; i < b.N; i++ {
   803  			logger.Debug("Send", "channel", chID, "conn", c, "msgBytes", bytesHexStringer(msgBytes))
   804  		}
   805  	})
   806  }
   807  
   808  func BenchmarkMConnectionLogReceiveMsg(b *testing.B) {
   809  	c := new(MConnection)
   810  	chID := byte(10)
   811  	msgBytes := []byte("Hello World!")
   812  
   813  	logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "benchmark")
   814  	var options []log.Option
   815  	options = append(options, log.AllowInfoWith("module", "benchmark"))
   816  	logger = log.NewFilter(logger, options...)
   817  
   818  	c.Logger = logger
   819  	b.ResetTimer()
   820  
   821  	b.Run("pool", func(b *testing.B) {
   822  		b.ReportAllocs()
   823  		for i := 0; i < b.N; i++ {
   824  			c.logReceiveMsg(chID, msgBytes)
   825  		}
   826  	})
   827  
   828  	b.Run("logger", func(b *testing.B) {
   829  		b.ReportAllocs()
   830  		for i := 0; i < b.N; i++ {
   831  			logger.Debug("Received bytes", "chID", chID, "msgBytes", bytesHexStringer(msgBytes))
   832  		}
   833  	})
   834  }
   835  
   836  func BenchmarkChannelLogRecvPacketMsg(b *testing.B) {
   837  	conn := new(MConnection)
   838  	c := new(Channel)
   839  	chID := byte(10)
   840  	msgBytes := []byte("Hello World!")
   841  	pk := PacketMsg{
   842  		ChannelID: chID,
   843  		EOF:       25,
   844  		Bytes:     msgBytes,
   845  	}
   846  
   847  	logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)).With("module", "benchmark")
   848  	var options []log.Option
   849  	options = append(options, log.AllowInfoWith("module", "benchmark"))
   850  	logger = log.NewFilter(logger, options...)
   851  
   852  	c.Logger = logger
   853  	c.conn = conn
   854  	b.ResetTimer()
   855  
   856  	b.Run("pool", func(b *testing.B) {
   857  		b.ReportAllocs()
   858  		for i := 0; i < b.N; i++ {
   859  			c.logRecvPacketMsg(pk)
   860  		}
   861  	})
   862  
   863  	b.Run("logger", func(b *testing.B) {
   864  		b.ReportAllocs()
   865  		for i := 0; i < b.N; i++ {
   866  			c.Logger.Debug("Read PacketMsg", "conn", c.conn, "packet", pk)
   867  		}
   868  	})
   869  }
   870  
   871  func TestTimer(t *testing.T) {
   872  	timer := time.NewTimer(1 * time.Second)
   873  	stoped := timer.Stop()
   874  	require.True(t, stoped)
   875  
   876  	var timerChHashData bool
   877  	select {
   878  	case <-timer.C:
   879  		timerChHashData = true
   880  	default:
   881  		timerChHashData = false
   882  	}
   883  	require.False(t, timerChHashData)
   884  
   885  	timer.Reset(1 * time.Second)
   886  
   887  	time.Sleep(2 * time.Second)
   888  
   889  	stoped = timer.Stop()
   890  	require.False(t, stoped)
   891  
   892  	if !stoped {
   893  		select {
   894  		case <-timer.C:
   895  			timerChHashData = true
   896  		default:
   897  			timerChHashData = false
   898  		}
   899  	}
   900  	require.True(t, timerChHashData)
   901  
   902  	timer.Reset(1 * time.Second)
   903  	now := time.Now()
   904  	<-timer.C
   905  	since := time.Since(now)
   906  	require.True(t, since > 500*time.Millisecond)
   907  
   908  	stoped = timer.Stop()
   909  	require.False(t, stoped)
   910  	if !stoped {
   911  		//_, ok := <-timer.C
   912  		//t.Log("ok:", ok)
   913  		select {
   914  		case <-timer.C:
   915  			timerChHashData = true
   916  		default:
   917  			timerChHashData = false
   918  		}
   919  	}
   920  	require.False(t, timerChHashData)
   921  }