github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/tendermint/p2p/conn/connection.go (about)

     1  package conn
     2  
     3  import (
     4  	"bufio"
     5  	"bytes"
     6  	"encoding/binary"
     7  	"runtime/debug"
     8  
     9  	"fmt"
    10  	"io"
    11  	"math"
    12  	"net"
    13  	"reflect"
    14  	"sync"
    15  	"sync/atomic"
    16  	"time"
    17  
    18  	"github.com/pkg/errors"
    19  
    20  	amino "github.com/tendermint/go-amino"
    21  
    22  	flow "github.com/fibonacci-chain/fbc/libs/tendermint/libs/flowrate"
    23  	"github.com/fibonacci-chain/fbc/libs/tendermint/libs/log"
    24  	tmmath "github.com/fibonacci-chain/fbc/libs/tendermint/libs/math"
    25  	"github.com/fibonacci-chain/fbc/libs/tendermint/libs/service"
    26  	"github.com/fibonacci-chain/fbc/libs/tendermint/libs/timer"
    27  )
    28  
    29  const (
    30  	defaultMaxPacketMsgPayloadSize = 1024
    31  
    32  	numBatchPacketMsgs = 10
    33  	minReadBufferSize  = 1024
    34  	minWriteBufferSize = 65536
    35  	updateStats        = 2 * time.Second
    36  
    37  	// some of these defaults are written in the user config
    38  	// flushThrottle, sendRate, recvRate
    39  	// TODO: remove values present in config
    40  	defaultFlushThrottle = 100 * time.Millisecond
    41  
    42  	defaultSendQueueCapacity   = 1
    43  	defaultRecvBufferCapacity  = 4096
    44  	defaultRecvMessageCapacity = 22020096      // 21MB
    45  	defaultSendRate            = int64(512000) // 500KB/s
    46  	defaultRecvRate            = int64(512000) // 500KB/s
    47  	defaultSendTimeout         = 10 * time.Second
    48  	defaultPingInterval        = 60 * time.Second
    49  	defaultPongTimeout         = 45 * time.Second
    50  )
    51  
    52  type logData struct {
    53  	Params [6]interface{}
    54  	Bytes  bytesHexStringer
    55  	Packet PacketMsg
    56  }
    57  
    58  var logDataPool = &sync.Pool{
    59  	New: func() interface{} {
    60  		return &logData{}
    61  	},
    62  }
    63  
    64  type receiveCbFunc func(chID byte, msgBytes []byte)
    65  type errorCbFunc func(interface{})
    66  
    67  type bytesHexStringer []byte
    68  
    69  func (b bytesHexStringer) String() string {
    70  	return fmt.Sprintf("%X", []byte(b))
    71  }
    72  
    73  /*
    74  Each peer has one `MConnection` (multiplex connection) instance.
    75  
    76  __multiplex__ *noun* a system or signal involving simultaneous transmission of
    77  several messages along a single channel of communication.
    78  
    79  Each `MConnection` handles message transmission on multiple abstract communication
    80  `Channel`s.  Each channel has a globally unique byte id.
    81  The byte id and the relative priorities of each `Channel` are configured upon
    82  initialization of the connection.
    83  
    84  There are two methods for sending messages:
    85  
    86  	func (m MConnection) Send(chID byte, msgBytes []byte) bool {}
    87  	func (m MConnection) TrySend(chID byte, msgBytes []byte}) bool {}
    88  
    89  `Send(chID, msgBytes)` is a blocking call that waits until `msg` is
    90  successfully queued for the channel with the given id byte `chID`, or until the
    91  request times out.  The message `msg` is serialized using Go-Amino.
    92  
    93  `TrySend(chID, msgBytes)` is a nonblocking call that returns false if the
    94  channel's queue is full.
    95  
    96  Inbound message bytes are handled with an onReceive callback function.
    97  */
    98  type MConnection struct {
    99  	service.BaseService
   100  
   101  	conn          net.Conn
   102  	bufConnReader *bufio.Reader
   103  	bufConnWriter *bufio.Writer
   104  	sendMonitor   *flow.Monitor
   105  	recvMonitor   *flow.Monitor
   106  	send          chan struct{}
   107  	pong          chan struct{}
   108  	channels      []*Channel
   109  	channelsIdx   map[byte]*Channel
   110  	onReceive     receiveCbFunc
   111  	onError       errorCbFunc
   112  	errored       uint32
   113  	config        MConnConfig
   114  
   115  	// Closing quitSendRoutine will cause the sendRoutine to eventually quit.
   116  	// doneSendRoutine is closed when the sendRoutine actually quits.
   117  	quitSendRoutine chan struct{}
   118  	doneSendRoutine chan struct{}
   119  
   120  	// Closing quitRecvRouting will cause the recvRouting to eventually quit.
   121  	quitRecvRoutine chan struct{}
   122  
   123  	// used to ensure FlushStop and OnStop
   124  	// are safe to call concurrently.
   125  	stopMtx sync.Mutex
   126  
   127  	flushTimer *timer.ThrottleTimer // flush writes as necessary but throttled.
   128  	pingTimer  *time.Ticker         // send pings periodically
   129  
   130  	// close conn if pong is not received in pongTimeout
   131  	pongTimer     *time.Timer
   132  	pongTimeoutCh chan bool // true - timeout, false - peer sent pong
   133  
   134  	chStatsTimer *time.Ticker // update channel stats periodically
   135  
   136  	created time.Time // time of creation
   137  
   138  	_maxPacketMsgSize int
   139  }
   140  
   141  // MConnConfig is a MConnection configuration.
   142  type MConnConfig struct {
   143  	SendRate int64 `mapstructure:"send_rate"`
   144  	RecvRate int64 `mapstructure:"recv_rate"`
   145  
   146  	// Maximum payload size
   147  	MaxPacketMsgPayloadSize int `mapstructure:"max_packet_msg_payload_size"`
   148  
   149  	// Interval to flush writes (throttled)
   150  	FlushThrottle time.Duration `mapstructure:"flush_throttle"`
   151  
   152  	// Interval to send pings
   153  	PingInterval time.Duration `mapstructure:"ping_interval"`
   154  
   155  	// Maximum wait time for pongs
   156  	PongTimeout time.Duration `mapstructure:"pong_timeout"`
   157  }
   158  
   159  // DefaultMConnConfig returns the default config.
   160  func DefaultMConnConfig() MConnConfig {
   161  	return MConnConfig{
   162  		SendRate:                defaultSendRate,
   163  		RecvRate:                defaultRecvRate,
   164  		MaxPacketMsgPayloadSize: defaultMaxPacketMsgPayloadSize,
   165  		FlushThrottle:           defaultFlushThrottle,
   166  		PingInterval:            defaultPingInterval,
   167  		PongTimeout:             defaultPongTimeout,
   168  	}
   169  }
   170  
   171  // NewMConnection wraps net.Conn and creates multiplex connection
   172  func NewMConnection(
   173  	conn net.Conn,
   174  	chDescs []*ChannelDescriptor,
   175  	onReceive receiveCbFunc,
   176  	onError errorCbFunc,
   177  ) *MConnection {
   178  	return NewMConnectionWithConfig(
   179  		conn,
   180  		chDescs,
   181  		onReceive,
   182  		onError,
   183  		DefaultMConnConfig())
   184  }
   185  
   186  // NewMConnectionWithConfig wraps net.Conn and creates multiplex connection with a config
   187  func NewMConnectionWithConfig(
   188  	conn net.Conn,
   189  	chDescs []*ChannelDescriptor,
   190  	onReceive receiveCbFunc,
   191  	onError errorCbFunc,
   192  	config MConnConfig,
   193  ) *MConnection {
   194  	if config.PongTimeout >= config.PingInterval {
   195  		panic("pongTimeout must be less than pingInterval (otherwise, next ping will reset pong timer)")
   196  	}
   197  
   198  	mconn := &MConnection{
   199  		conn:          conn,
   200  		bufConnReader: bufio.NewReaderSize(conn, minReadBufferSize),
   201  		bufConnWriter: bufio.NewWriterSize(conn, minWriteBufferSize),
   202  		sendMonitor:   flow.New(0, 0),
   203  		recvMonitor:   flow.New(0, 0),
   204  		send:          make(chan struct{}, 1),
   205  		pong:          make(chan struct{}, 1),
   206  		onReceive:     onReceive,
   207  		onError:       onError,
   208  		config:        config,
   209  		created:       time.Now(),
   210  	}
   211  
   212  	// Create channels
   213  	var channelsIdx = map[byte]*Channel{}
   214  	var channels = []*Channel{}
   215  
   216  	for _, desc := range chDescs {
   217  		channel := newChannel(mconn, *desc)
   218  		channelsIdx[channel.desc.ID] = channel
   219  		channels = append(channels, channel)
   220  	}
   221  	mconn.channels = channels
   222  	mconn.channelsIdx = channelsIdx
   223  
   224  	mconn.BaseService = *service.NewBaseService(nil, "MConnection", mconn)
   225  
   226  	// maxPacketMsgSize() is a bit heavy, so call just once
   227  	mconn._maxPacketMsgSize = mconn.maxPacketMsgSize()
   228  
   229  	return mconn
   230  }
   231  
   232  func (c *MConnection) SetLogger(l log.Logger) {
   233  	c.BaseService.SetLogger(l)
   234  	for _, ch := range c.channels {
   235  		ch.SetLogger(l)
   236  	}
   237  }
   238  
   239  // OnStart implements BaseService
   240  func (c *MConnection) OnStart() error {
   241  	if err := c.BaseService.OnStart(); err != nil {
   242  		return err
   243  	}
   244  	c.flushTimer = timer.NewThrottleTimer("flush", c.config.FlushThrottle)
   245  	c.pingTimer = time.NewTicker(c.config.PingInterval)
   246  	c.pongTimeoutCh = make(chan bool, 1)
   247  	c.chStatsTimer = time.NewTicker(updateStats)
   248  	c.quitSendRoutine = make(chan struct{})
   249  	c.doneSendRoutine = make(chan struct{})
   250  	c.quitRecvRoutine = make(chan struct{})
   251  	go c.sendRoutine()
   252  	go c.recvRoutine()
   253  	return nil
   254  }
   255  
   256  // stopServices stops the BaseService and timers and closes the quitSendRoutine.
   257  // if the quitSendRoutine was already closed, it returns true, otherwise it returns false.
   258  // It uses the stopMtx to ensure only one of FlushStop and OnStop can do this at a time.
   259  func (c *MConnection) stopServices() (alreadyStopped bool) {
   260  	c.stopMtx.Lock()
   261  	defer c.stopMtx.Unlock()
   262  
   263  	select {
   264  	case <-c.quitSendRoutine:
   265  		// already quit
   266  		return true
   267  	default:
   268  	}
   269  
   270  	select {
   271  	case <-c.quitRecvRoutine:
   272  		// already quit
   273  		return true
   274  	default:
   275  	}
   276  
   277  	c.BaseService.OnStop()
   278  	c.flushTimer.Stop()
   279  	c.pingTimer.Stop()
   280  	c.chStatsTimer.Stop()
   281  
   282  	// inform the recvRouting that we are shutting down
   283  	close(c.quitRecvRoutine)
   284  	close(c.quitSendRoutine)
   285  	return false
   286  }
   287  
   288  // FlushStop replicates the logic of OnStop.
   289  // It additionally ensures that all successful
   290  // .Send() calls will get flushed before closing
   291  // the connection.
   292  func (c *MConnection) FlushStop() {
   293  	if c.stopServices() {
   294  		return
   295  	}
   296  
   297  	// this block is unique to FlushStop
   298  	{
   299  		// wait until the sendRoutine exits
   300  		// so we dont race on calling sendSomePacketMsgs
   301  		<-c.doneSendRoutine
   302  
   303  		// Send and flush all pending msgs.
   304  		// Since sendRoutine has exited, we can call this
   305  		// safely
   306  		eof := c.sendSomePacketMsgs()
   307  		for !eof {
   308  			eof = c.sendSomePacketMsgs()
   309  		}
   310  		c.flush()
   311  
   312  		// Now we can close the connection
   313  	}
   314  
   315  	c.conn.Close() // nolint: errcheck
   316  
   317  	// We can't close pong safely here because
   318  	// recvRoutine may write to it after we've stopped.
   319  	// Though it doesn't need to get closed at all,
   320  	// we close it @ recvRoutine.
   321  
   322  	// c.Stop()
   323  }
   324  
   325  // OnStop implements BaseService
   326  func (c *MConnection) OnStop() {
   327  	if c.stopServices() {
   328  		return
   329  	}
   330  
   331  	c.conn.Close() // nolint: errcheck
   332  
   333  	// We can't close pong safely here because
   334  	// recvRoutine may write to it after we've stopped.
   335  	// Though it doesn't need to get closed at all,
   336  	// we close it @ recvRoutine.
   337  }
   338  
   339  func (c *MConnection) String() string {
   340  	return fmt.Sprintf("MConn{%v}", c.conn.RemoteAddr())
   341  }
   342  
   343  func (c *MConnection) flush() {
   344  	c.Logger.Debug("Flush", "conn", c)
   345  	err := c.bufConnWriter.Flush()
   346  	if err != nil {
   347  		c.Logger.Error("MConnection flush failed", "err", err)
   348  	}
   349  }
   350  
   351  // Catch panics, usually caused by remote disconnects.
   352  func (c *MConnection) _recover() {
   353  	if r := recover(); r != nil {
   354  		c.Logger.Error("MConnection panicked", "err", r, "stack", string(debug.Stack()))
   355  		c.stopForError(errors.Errorf("recovered from panic: %v", r))
   356  	}
   357  }
   358  
   359  func (c *MConnection) stopForError(r interface{}) {
   360  	c.Stop()
   361  	if atomic.CompareAndSwapUint32(&c.errored, 0, 1) {
   362  		if c.onError != nil {
   363  			c.onError(r)
   364  		}
   365  	}
   366  }
   367  
   368  func (c *MConnection) logSendData(msg string, chID byte, msgBytes []byte) {
   369  	logParams := logDataPool.Get().(*logData)
   370  	logParams.Bytes = msgBytes
   371  	params := &logParams.Params
   372  	params[0] = "channel"
   373  	params[1] = chID
   374  	params[2] = "conn"
   375  	params[3] = c
   376  	params[4] = "msgBytes"
   377  	params[5] = &logParams.Bytes
   378  
   379  	c.Logger.Debug(msg, logParams.Params[:]...)
   380  	logDataPool.Put(logParams)
   381  }
   382  
   383  // Queues a message to be sent to channel.
   384  func (c *MConnection) Send(chID byte, msgBytes []byte) bool {
   385  	if !c.IsRunning() {
   386  		return false
   387  	}
   388  
   389  	c.logSendData("Send", chID, msgBytes)
   390  
   391  	// Send message to channel.
   392  	channel, ok := c.channelsIdx[chID]
   393  	if !ok {
   394  		c.Logger.Error(fmt.Sprintf("Cannot send bytes, unknown channel %X", chID))
   395  		return false
   396  	}
   397  
   398  	success := channel.sendBytes(msgBytes)
   399  	if success {
   400  		// Wake up sendRoutine if necessary
   401  		select {
   402  		case c.send <- struct{}{}:
   403  		default:
   404  		}
   405  	} else {
   406  		c.logSendData("Send failed", chID, msgBytes)
   407  	}
   408  	return success
   409  }
   410  
   411  // Queues a message to be sent to channel.
   412  // Nonblocking, returns true if successful.
   413  func (c *MConnection) TrySend(chID byte, msgBytes []byte) bool {
   414  	if !c.IsRunning() {
   415  		return false
   416  	}
   417  
   418  	c.Logger.Debug("TrySend", "channel", chID, "conn", c, "msgBytes", fmt.Sprintf("%X", msgBytes))
   419  
   420  	// Send message to channel.
   421  	channel, ok := c.channelsIdx[chID]
   422  	if !ok {
   423  		c.Logger.Error(fmt.Sprintf("Cannot send bytes, unknown channel %X", chID))
   424  		return false
   425  	}
   426  
   427  	ok = channel.trySendBytes(msgBytes)
   428  	if ok {
   429  		// Wake up sendRoutine if necessary
   430  		select {
   431  		case c.send <- struct{}{}:
   432  		default:
   433  		}
   434  	}
   435  
   436  	return ok
   437  }
   438  
   439  // CanSend returns true if you can send more data onto the chID, false
   440  // otherwise. Use only as a heuristic.
   441  func (c *MConnection) CanSend(chID byte) bool {
   442  	if !c.IsRunning() {
   443  		return false
   444  	}
   445  
   446  	channel, ok := c.channelsIdx[chID]
   447  	if !ok {
   448  		c.Logger.Error(fmt.Sprintf("Unknown channel %X", chID))
   449  		return false
   450  	}
   451  	return channel.canSend()
   452  }
   453  
   454  // sendRoutine polls for packets to send from channels.
   455  func (c *MConnection) sendRoutine() {
   456  	defer c._recover()
   457  
   458  FOR_LOOP:
   459  	for {
   460  		var _n int64
   461  		var err error
   462  	SELECTION:
   463  		select {
   464  		case <-c.flushTimer.Ch:
   465  			// NOTE: flushTimer.Set() must be called every time
   466  			// something is written to .bufConnWriter.
   467  			c.flush()
   468  		case <-c.chStatsTimer.C:
   469  			for _, channel := range c.channels {
   470  				channel.updateStats()
   471  			}
   472  		case <-c.pingTimer.C:
   473  			c.Logger.Debug("Send Ping")
   474  			_n, err = cdc.MarshalBinaryLengthPrefixedWriterWithRegiteredMarshaller(c.bufConnWriter, PacketPing{})
   475  			if err != nil {
   476  				_n, err = cdc.MarshalBinaryLengthPrefixedWriter(c.bufConnWriter, PacketPing{})
   477  			}
   478  			if err != nil {
   479  				break SELECTION
   480  			}
   481  			c.sendMonitor.Update(int(_n))
   482  			c.Logger.Debug("Starting pong timer", "dur", c.config.PongTimeout)
   483  			c.pongTimer = time.AfterFunc(c.config.PongTimeout, func() {
   484  				select {
   485  				case c.pongTimeoutCh <- true:
   486  				default:
   487  				}
   488  			})
   489  			c.flush()
   490  		case timeout := <-c.pongTimeoutCh:
   491  			if timeout {
   492  				c.Logger.Debug("Pong timeout")
   493  				err = errors.New("pong timeout")
   494  			} else {
   495  				c.stopPongTimer()
   496  			}
   497  		case <-c.pong:
   498  			c.Logger.Debug("Send Pong")
   499  			_n, err = cdc.MarshalBinaryLengthPrefixedWriterWithRegiteredMarshaller(c.bufConnWriter, PacketPong{})
   500  			if err != nil {
   501  				_n, err = cdc.MarshalBinaryLengthPrefixedWriter(c.bufConnWriter, PacketPong{})
   502  			}
   503  			if err != nil {
   504  				break SELECTION
   505  			}
   506  			c.sendMonitor.Update(int(_n))
   507  			c.flush()
   508  		case <-c.quitSendRoutine:
   509  			break FOR_LOOP
   510  		case <-c.send:
   511  			// Send some PacketMsgs
   512  			eof := c.sendSomePacketMsgs()
   513  			if !eof {
   514  				// Keep sendRoutine awake.
   515  				select {
   516  				case c.send <- struct{}{}:
   517  				default:
   518  				}
   519  			}
   520  		}
   521  
   522  		if !c.IsRunning() {
   523  			break FOR_LOOP
   524  		}
   525  		if err != nil {
   526  			c.Logger.Error("Connection failed @ sendRoutine", "conn", c, "err", err)
   527  			c.stopForError(err)
   528  			break FOR_LOOP
   529  		}
   530  	}
   531  
   532  	// Cleanup
   533  	c.stopPongTimer()
   534  	close(c.doneSendRoutine)
   535  }
   536  
   537  // Returns true if messages from channels were exhausted.
   538  // Blocks in accordance to .sendMonitor throttling.
   539  func (c *MConnection) sendSomePacketMsgs() bool {
   540  	// Block until .sendMonitor says we can write.
   541  	// Once we're ready we send more than we asked for,
   542  	// but amortized it should even out.
   543  	c.sendMonitor.Limit(c._maxPacketMsgSize, atomic.LoadInt64(&c.config.SendRate), true)
   544  
   545  	// Now send some PacketMsgs.
   546  	for i := 0; i < numBatchPacketMsgs; i++ {
   547  		if c.sendPacketMsg() {
   548  			return true
   549  		}
   550  	}
   551  	return false
   552  }
   553  
   554  // Returns true if messages from channels were exhausted.
   555  func (c *MConnection) sendPacketMsg() bool {
   556  	// Choose a channel to create a PacketMsg from.
   557  	// The chosen channel will be the one whose recentlySent/priority is the least.
   558  	var leastRatio float32 = math.MaxFloat32
   559  	var leastChannel *Channel
   560  	for _, channel := range c.channels {
   561  		// If nothing to send, skip this channel
   562  		if !channel.isSendPending() {
   563  			continue
   564  		}
   565  		// Get ratio, and keep track of lowest ratio.
   566  		ratio := float32(channel.recentlySent) / float32(channel.desc.Priority)
   567  		if ratio < leastRatio {
   568  			leastRatio = ratio
   569  			leastChannel = channel
   570  		}
   571  	}
   572  
   573  	// Nothing to send?
   574  	if leastChannel == nil {
   575  		return true
   576  	}
   577  	// c.Logger.Info("Found a msgPacket to send")
   578  
   579  	// Make & send a PacketMsg from this channel
   580  	_n, err := leastChannel.writePacketMsgTo(c.bufConnWriter)
   581  	if err != nil {
   582  		c.Logger.Error("Failed to write PacketMsg", "err", err)
   583  		c.stopForError(err)
   584  		return true
   585  	}
   586  	c.sendMonitor.Update(int(_n))
   587  	c.flushTimer.Set()
   588  	return false
   589  }
   590  
   591  // recvRoutine reads PacketMsgs and reconstructs the message using the channels' "recving" buffer.
   592  // After a whole message has been assembled, it's pushed to onReceive().
   593  // Blocks depending on how the connection is throttled.
   594  // Otherwise, it never blocks.
   595  func (c *MConnection) recvRoutine() {
   596  	defer c._recover()
   597  
   598  	var packetMsg PacketMsg
   599  FOR_LOOP:
   600  	for {
   601  		// Block until .recvMonitor says we can read.
   602  		c.recvMonitor.Limit(c._maxPacketMsgSize, atomic.LoadInt64(&c.config.RecvRate), true)
   603  
   604  		// Peek into bufConnReader for debugging
   605  		/*
   606  			if numBytes := c.bufConnReader.Buffered(); numBytes > 0 {
   607  				bz, err := c.bufConnReader.Peek(tmmath.MinInt(numBytes, 100))
   608  				if err == nil {
   609  					// return
   610  				} else {
   611  					c.Logger.Debug("Error peeking connection buffer", "err", err)
   612  					// return nil
   613  				}
   614  				c.Logger.Info("Peek connection buffer", "numBytes", numBytes, "bz", bz)
   615  			}
   616  		*/
   617  
   618  		// Read packet type
   619  		var packet Packet
   620  		var _n int64
   621  		var err error
   622  		// _n, err = cdc.UnmarshalBinaryLengthPrefixedReader(c.bufConnReader, &packet, int64(c._maxPacketMsgSize))
   623  		packet, _n, err = unmarshalPacketFromAminoReader(c.bufConnReader, int64(c._maxPacketMsgSize), &packetMsg)
   624  		c.recvMonitor.Update(int(_n))
   625  
   626  		if err != nil {
   627  			// stopServices was invoked and we are shutting down
   628  			// receiving is excpected to fail since we will close the connection
   629  			select {
   630  			case <-c.quitRecvRoutine:
   631  				break FOR_LOOP
   632  			default:
   633  			}
   634  
   635  			if c.IsRunning() {
   636  				if err == io.EOF {
   637  					c.Logger.Info("Connection is closed @ recvRoutine (likely by the other side)", "conn", c)
   638  				} else {
   639  					c.Logger.Error("Connection failed @ recvRoutine (reading byte)", "conn", c, "err", err)
   640  				}
   641  				c.stopForError(err)
   642  			}
   643  			break FOR_LOOP
   644  		}
   645  
   646  		// Read more depending on packet type.
   647  		switch pkt := packet.(type) {
   648  		case PacketPing:
   649  			// TODO: prevent abuse, as they cause flush()'s.
   650  			// https://github.com/tendermint/tendermint/issues/1190
   651  			c.Logger.Debug("Receive Ping")
   652  			select {
   653  			case c.pong <- struct{}{}:
   654  			default:
   655  				// never block
   656  			}
   657  		case PacketPong:
   658  			c.Logger.Debug("Receive Pong")
   659  			select {
   660  			case c.pongTimeoutCh <- false:
   661  			default:
   662  				// never block
   663  			}
   664  		case *PacketMsg:
   665  			channel, ok := c.channelsIdx[pkt.ChannelID]
   666  			if !ok || channel == nil {
   667  				err := fmt.Errorf("unknown channel %X", pkt.ChannelID)
   668  				c.Logger.Error("Connection failed @ recvRoutine", "conn", c, "err", err)
   669  				c.stopForError(err)
   670  				break FOR_LOOP
   671  			}
   672  
   673  			msgBytes, err := channel.recvPacketMsg(*pkt)
   674  			if err != nil {
   675  				if c.IsRunning() {
   676  					c.Logger.Error("Connection failed @ recvRoutine", "conn", c, "err", err)
   677  					c.stopForError(err)
   678  				}
   679  				break FOR_LOOP
   680  			}
   681  			if msgBytes != nil {
   682  				c.logReceiveMsg(pkt.ChannelID, msgBytes)
   683  				// NOTE: This means the reactor.Receive runs in the same thread as the p2p recv routine
   684  				c.onReceive(pkt.ChannelID, msgBytes)
   685  			}
   686  		default:
   687  			err := fmt.Errorf("unknown message type %v", reflect.TypeOf(packet))
   688  			c.Logger.Error("Connection failed @ recvRoutine", "conn", c, "err", err)
   689  			c.stopForError(err)
   690  			break FOR_LOOP
   691  		}
   692  	}
   693  
   694  	// Cleanup
   695  	close(c.pong)
   696  	for range c.pong {
   697  		// Drain
   698  	}
   699  }
   700  
   701  func (c *MConnection) logReceiveMsg(channelID byte, msgBytes []byte) {
   702  	logParams := logDataPool.Get().(*logData)
   703  	logParams.Bytes = msgBytes
   704  	params := &logParams.Params
   705  	params[0] = "chID"
   706  	params[1] = channelID
   707  	params[2] = "msgBytes"
   708  	params[3] = &logParams.Bytes
   709  	c.Logger.Debug("Received bytes", logParams.Params[:4]...)
   710  	logDataPool.Put(logParams)
   711  }
   712  
   713  // not goroutine-safe
   714  func (c *MConnection) stopPongTimer() {
   715  	if c.pongTimer != nil {
   716  		_ = c.pongTimer.Stop()
   717  		c.pongTimer = nil
   718  	}
   719  }
   720  
   721  // maxPacketMsgSize returns a maximum size of PacketMsg, including the overhead
   722  // of amino encoding.
   723  func (c *MConnection) maxPacketMsgSize() int {
   724  	return len(cdc.MustMarshalBinaryLengthPrefixed(PacketMsg{
   725  		ChannelID: 0x01,
   726  		EOF:       1,
   727  		Bytes:     make([]byte, c.config.MaxPacketMsgPayloadSize),
   728  	})) + 10 // leave room for changes in amino
   729  }
   730  
   731  type ConnectionStatus struct {
   732  	Duration    time.Duration
   733  	SendMonitor flow.Status
   734  	RecvMonitor flow.Status
   735  	Channels    []ChannelStatus
   736  }
   737  
   738  type ChannelStatus struct {
   739  	ID                byte
   740  	SendQueueCapacity int
   741  	SendQueueSize     int
   742  	Priority          int
   743  	RecentlySent      int64
   744  }
   745  
   746  func (c *MConnection) Status() ConnectionStatus {
   747  	var status ConnectionStatus
   748  	status.Duration = time.Since(c.created)
   749  	status.SendMonitor = c.sendMonitor.Status()
   750  	status.RecvMonitor = c.recvMonitor.Status()
   751  	status.Channels = make([]ChannelStatus, len(c.channels))
   752  	for i, channel := range c.channels {
   753  		status.Channels[i] = ChannelStatus{
   754  			ID:                channel.desc.ID,
   755  			SendQueueCapacity: cap(channel.sendQueue),
   756  			SendQueueSize:     int(atomic.LoadInt32(&channel.sendQueueSize)),
   757  			Priority:          channel.desc.Priority,
   758  			RecentlySent:      atomic.LoadInt64(&channel.recentlySent),
   759  		}
   760  	}
   761  	return status
   762  }
   763  
   764  //-----------------------------------------------------------------------------
   765  
   766  type ChannelDescriptor struct {
   767  	ID                  byte
   768  	Priority            int
   769  	SendQueueCapacity   int
   770  	RecvBufferCapacity  int
   771  	RecvMessageCapacity int
   772  }
   773  
   774  func (chDesc ChannelDescriptor) FillDefaults() (filled ChannelDescriptor) {
   775  	if chDesc.SendQueueCapacity == 0 {
   776  		chDesc.SendQueueCapacity = defaultSendQueueCapacity
   777  	}
   778  	if chDesc.RecvBufferCapacity == 0 {
   779  		chDesc.RecvBufferCapacity = defaultRecvBufferCapacity
   780  	}
   781  	if chDesc.RecvMessageCapacity == 0 {
   782  		chDesc.RecvMessageCapacity = defaultRecvMessageCapacity
   783  	}
   784  	filled = chDesc
   785  	return
   786  }
   787  
   788  // TODO: lowercase.
   789  // NOTE: not goroutine-safe.
   790  type Channel struct {
   791  	conn          *MConnection
   792  	desc          ChannelDescriptor
   793  	sendQueue     chan []byte
   794  	sendQueueSize int32 // atomic.
   795  	recving       []byte
   796  	sending       []byte
   797  	recentlySent  int64 // exponential moving average
   798  
   799  	maxPacketMsgPayloadSize int
   800  
   801  	Logger log.Logger
   802  }
   803  
   804  func newChannel(conn *MConnection, desc ChannelDescriptor) *Channel {
   805  	desc = desc.FillDefaults()
   806  	if desc.Priority <= 0 {
   807  		panic("Channel default priority must be a positive integer")
   808  	}
   809  	return &Channel{
   810  		conn:                    conn,
   811  		desc:                    desc,
   812  		sendQueue:               make(chan []byte, desc.SendQueueCapacity),
   813  		recving:                 make([]byte, 0, desc.RecvBufferCapacity),
   814  		maxPacketMsgPayloadSize: conn.config.MaxPacketMsgPayloadSize,
   815  	}
   816  }
   817  
   818  func (ch *Channel) SetLogger(l log.Logger) {
   819  	ch.Logger = l
   820  }
   821  
   822  var sendTimerPool = &sync.Pool{
   823  	New: func() interface{} {
   824  		return time.NewTimer(defaultSendTimeout)
   825  	},
   826  }
   827  
   828  // Queues message to send to this channel.
   829  // Goroutine-safe
   830  // Times out (and returns false) after defaultSendTimeout
   831  func (ch *Channel) sendBytes(bytes []byte) bool {
   832  	sendTimer := sendTimerPool.Get().(*time.Timer)
   833  	if !sendTimer.Stop() {
   834  		select {
   835  		case <-sendTimer.C:
   836  		default:
   837  		}
   838  	}
   839  	sendTimer.Reset(defaultSendTimeout)
   840  	select {
   841  	case ch.sendQueue <- bytes:
   842  		sendTimerPool.Put(sendTimer)
   843  		atomic.AddInt32(&ch.sendQueueSize, 1)
   844  		return true
   845  	case <-sendTimer.C:
   846  		sendTimerPool.Put(sendTimer)
   847  		return false
   848  	}
   849  }
   850  
   851  // Queues message to send to this channel.
   852  // Nonblocking, returns true if successful.
   853  // Goroutine-safe
   854  func (ch *Channel) trySendBytes(bytes []byte) bool {
   855  	select {
   856  	case ch.sendQueue <- bytes:
   857  		atomic.AddInt32(&ch.sendQueueSize, 1)
   858  		return true
   859  	default:
   860  		return false
   861  	}
   862  }
   863  
   864  // Goroutine-safe
   865  func (ch *Channel) loadSendQueueSize() (size int) {
   866  	return int(atomic.LoadInt32(&ch.sendQueueSize))
   867  }
   868  
   869  // Goroutine-safe
   870  // Use only as a heuristic.
   871  func (ch *Channel) canSend() bool {
   872  	return ch.loadSendQueueSize() < defaultSendQueueCapacity
   873  }
   874  
   875  // Returns true if any PacketMsgs are pending to be sent.
   876  // Call before calling nextPacketMsg()
   877  // Goroutine-safe
   878  func (ch *Channel) isSendPending() bool {
   879  	if len(ch.sending) == 0 {
   880  		if len(ch.sendQueue) == 0 {
   881  			return false
   882  		}
   883  		ch.sending = <-ch.sendQueue
   884  	}
   885  	return true
   886  }
   887  
   888  // Creates a new PacketMsg to send.
   889  // Not goroutine-safe
   890  func (ch *Channel) nextPacketMsg() PacketMsg {
   891  	packet := PacketMsg{}
   892  	packet.ChannelID = ch.desc.ID
   893  	maxSize := ch.maxPacketMsgPayloadSize
   894  	packet.Bytes = ch.sending[:tmmath.MinInt(maxSize, len(ch.sending))]
   895  	if len(ch.sending) <= maxSize {
   896  		packet.EOF = byte(0x01)
   897  		ch.sending = nil
   898  		atomic.AddInt32(&ch.sendQueueSize, -1) // decrement sendQueueSize
   899  	} else {
   900  		packet.EOF = byte(0x00)
   901  		ch.sending = ch.sending[tmmath.MinInt(maxSize, len(ch.sending)):]
   902  	}
   903  	return packet
   904  }
   905  
   906  var packetBzSendPool = &sync.Pool{
   907  	New: func() interface{} {
   908  		return &bytes.Buffer{}
   909  	},
   910  }
   911  
   912  // Writes next PacketMsg to w and updates c.recentlySent.
   913  // Not goroutine-safe
   914  func (ch *Channel) writePacketMsgTo(w io.Writer) (n int64, err error) {
   915  	var packet = ch.nextPacketMsg()
   916  
   917  	packetMsgTypePrefix := getPacketMsgAminoTypePrefix()
   918  	bzSize := len(packetMsgTypePrefix) + packet.AminoSize(cdc)
   919  	bzSizeWithLenPrefix := amino.UvarintSize(uint64(bzSize)) + bzSize
   920  
   921  	// var buf = bytes.NewBuffer(make([]byte, 0, bzSizeWithLenPrefix))
   922  	buf := packetBzSendPool.Get().(*bytes.Buffer)
   923  	defer packetBzSendPool.Put(buf)
   924  	buf.Reset()
   925  	buf.Grow(bzSizeWithLenPrefix)
   926  
   927  	err = amino.EncodeUvarintToBuffer(buf, uint64(bzSize))
   928  	if err == nil {
   929  		buf.Write(packetMsgTypePrefix)
   930  		err = packet.MarshalAminoTo(cdc, buf)
   931  		if err == nil && buf.Len() == bzSizeWithLenPrefix {
   932  			bzNum := 0
   933  			bzNum, err = w.Write(buf.Bytes())
   934  			n = int64(bzNum)
   935  			atomic.AddInt64(&ch.recentlySent, n)
   936  			return
   937  		}
   938  	}
   939  
   940  	n, err = cdc.MarshalBinaryLengthPrefixedWriterWithRegiteredMarshaller(w, packet)
   941  	if err != nil {
   942  		n, err = cdc.MarshalBinaryLengthPrefixedWriter(w, packet)
   943  	}
   944  	atomic.AddInt64(&ch.recentlySent, n)
   945  	return
   946  }
   947  
   948  func (ch *Channel) logRecvPacketMsg(packet PacketMsg) {
   949  	logParams := logDataPool.Get().(*logData)
   950  	logParams.Packet = packet
   951  	params := &logParams.Params
   952  	params[0] = "conn"
   953  	params[1] = ch.conn
   954  	params[2] = "packet"
   955  	params[3] = &logParams.Packet
   956  	ch.Logger.Debug("Read PacketMsg", logParams.Params[:4]...)
   957  	logDataPool.Put(logParams)
   958  }
   959  
   960  // Handles incoming PacketMsgs. It returns a message bytes if message is
   961  // complete. NOTE message bytes may change on next call to recvPacketMsg.
   962  // Not goroutine-safe
   963  func (ch *Channel) recvPacketMsg(packet PacketMsg) ([]byte, error) {
   964  	ch.logRecvPacketMsg(packet)
   965  
   966  	var recvCap, recvReceived = ch.desc.RecvMessageCapacity, len(ch.recving) + len(packet.Bytes)
   967  	if recvCap < recvReceived {
   968  		return nil, fmt.Errorf("received message exceeds available capacity: %v < %v", recvCap, recvReceived)
   969  	}
   970  	ch.recving = append(ch.recving, packet.Bytes...)
   971  	if packet.EOF == byte(0x01) {
   972  		msgBytes := ch.recving
   973  
   974  		// clear the slice without re-allocating.
   975  		// http://stackoverflow.com/questions/16971741/how-do-you-clear-a-slice-in-go
   976  		//   suggests this could be a memory leak, but we might as well keep the memory for the channel until it closes,
   977  		//	at which point the recving slice stops being used and should be garbage collected
   978  		ch.recving = ch.recving[:0] // make([]byte, 0, ch.desc.RecvBufferCapacity)
   979  		return msgBytes, nil
   980  	}
   981  	return nil, nil
   982  }
   983  
   984  // Call this periodically to update stats for throttling purposes.
   985  // Not goroutine-safe
   986  func (ch *Channel) updateStats() {
   987  	// Exponential decay of stats.
   988  	// TODO: optimize.
   989  	atomic.StoreInt64(&ch.recentlySent, int64(float64(atomic.LoadInt64(&ch.recentlySent))*0.8))
   990  }
   991  
   992  //----------------------------------------
   993  // Packet
   994  
   995  type Packet interface {
   996  	AssertIsPacket()
   997  }
   998  
   999  const (
  1000  	PacketPingName = "tendermint/p2p/PacketPing"
  1001  	PacketPongName = "tendermint/p2p/PacketPong"
  1002  	PacketMsgName  = "tendermint/p2p/PacketMsg"
  1003  )
  1004  
  1005  func RegisterPacket(cdc *amino.Codec) {
  1006  	cdc.RegisterInterface((*Packet)(nil), nil)
  1007  	cdc.RegisterConcrete(PacketPing{}, PacketPingName, nil)
  1008  	cdc.RegisterConcrete(PacketPong{}, PacketPongName, nil)
  1009  	cdc.RegisterConcrete(&PacketMsg{}, PacketMsgName, nil)
  1010  
  1011  	cdc.RegisterConcreteMarshaller(PacketPingName, func(_ *amino.Codec, i interface{}) ([]byte, error) {
  1012  		return []byte{}, nil
  1013  	})
  1014  	cdc.RegisterConcreteMarshaller(PacketPongName, func(_ *amino.Codec, i interface{}) ([]byte, error) {
  1015  		return []byte{}, nil
  1016  	})
  1017  	cdc.RegisterConcreteMarshaller(PacketMsgName, func(codec *amino.Codec, i interface{}) ([]byte, error) {
  1018  		if packet, ok := i.(PacketMsg); ok {
  1019  			return packet.MarshalToAmino(codec)
  1020  		} else if ppacket, ok := i.(*PacketMsg); ok {
  1021  			return ppacket.MarshalToAmino(codec)
  1022  		} else {
  1023  			return nil, fmt.Errorf("%v must be of type %v", i, PacketMsg{})
  1024  		}
  1025  	})
  1026  	cdc.RegisterConcreteUnmarshaller(PacketPingName, func(_ *amino.Codec, _ []byte) (interface{}, int, error) {
  1027  		return PacketPing{}, 0, nil
  1028  	})
  1029  	cdc.RegisterConcreteUnmarshaller(PacketPongName, func(_ *amino.Codec, _ []byte) (interface{}, int, error) {
  1030  		return PacketPong{}, 0, nil
  1031  	})
  1032  	cdc.RegisterConcreteUnmarshaller(PacketMsgName, func(codec *amino.Codec, data []byte) (interface{}, int, error) {
  1033  		var msg PacketMsg
  1034  		err := msg.UnmarshalFromAmino(codec, data)
  1035  		if err != nil {
  1036  			return nil, 0, err
  1037  		} else {
  1038  			return &msg, len(data), nil
  1039  		}
  1040  	})
  1041  
  1042  	cdc.EnableBufferMarshaler(PacketMsg{})
  1043  }
  1044  
  1045  func (PacketPing) AssertIsPacket() {}
  1046  func (PacketPong) AssertIsPacket() {}
  1047  func (PacketMsg) AssertIsPacket()  {}
  1048  
  1049  type PacketPing struct {
  1050  }
  1051  
  1052  func (p *PacketPing) UnmarshalFromAmino(_ *amino.Codec, _ []byte) error {
  1053  	return nil
  1054  }
  1055  
  1056  func (PacketPing) MarshalToAmino(_ *amino.Codec) ([]byte, error) {
  1057  	return []byte{}, nil
  1058  }
  1059  
  1060  type PacketPong struct {
  1061  }
  1062  
  1063  func (PacketPong) MarshalToAmino(_ *amino.Codec) ([]byte, error) {
  1064  	return []byte{}, nil
  1065  }
  1066  
  1067  func (p *PacketPong) UnmarshalFromAmino(_ *amino.Codec, _ []byte) error {
  1068  	return nil
  1069  }
  1070  
  1071  type PacketMsg struct {
  1072  	ChannelID byte
  1073  	EOF       byte // 1 means message ends here.
  1074  	Bytes     []byte
  1075  }
  1076  
  1077  func (mp PacketMsg) String() string {
  1078  	return fmt.Sprintf("PacketMsg{%X:%X T:%X}", mp.ChannelID, mp.Bytes, mp.EOF)
  1079  }
  1080  
  1081  func (mp *PacketMsg) Reset() {
  1082  	mp.ChannelID = 0
  1083  	mp.EOF = 0
  1084  	mp.Bytes = mp.Bytes[:0]
  1085  }
  1086  
  1087  func (mp PacketMsg) AminoSize(_ *amino.Codec) int {
  1088  	size := 0
  1089  	if mp.ChannelID != 0 {
  1090  		if mp.ChannelID <= 0b0111_1111 {
  1091  			size += 2
  1092  		} else {
  1093  			size += 3
  1094  		}
  1095  	}
  1096  
  1097  	if mp.EOF != 0 {
  1098  		if mp.EOF <= 0b0111_1111 {
  1099  			size += 2
  1100  		} else {
  1101  			size += 3
  1102  		}
  1103  	}
  1104  
  1105  	if len(mp.Bytes) != 0 {
  1106  		size += 1 + amino.ByteSliceSize(mp.Bytes)
  1107  	}
  1108  
  1109  	return size
  1110  }
  1111  
  1112  func (mp PacketMsg) MarshalToAmino(cdc *amino.Codec) ([]byte, error) {
  1113  	var buf bytes.Buffer
  1114  	buf.Grow(mp.AminoSize(cdc))
  1115  	err := mp.MarshalAminoTo(cdc, &buf)
  1116  	if err != nil {
  1117  		return nil, err
  1118  	}
  1119  	return buf.Bytes(), nil
  1120  }
  1121  
  1122  func (mp PacketMsg) MarshalAminoTo(_ *amino.Codec, buf *bytes.Buffer) error {
  1123  	var err error
  1124  	// field 1
  1125  	if mp.ChannelID != 0 {
  1126  		const pbKey = 1 << 3
  1127  		buf.WriteByte(pbKey)
  1128  		if mp.ChannelID <= 0b0111_1111 {
  1129  			buf.WriteByte(mp.ChannelID)
  1130  		} else {
  1131  			buf.WriteByte(0b1000_0000 | (mp.ChannelID & 0x7F))
  1132  			buf.WriteByte(mp.ChannelID >> 7)
  1133  		}
  1134  	}
  1135  
  1136  	// field 2
  1137  	if mp.EOF != 0 {
  1138  		const pbKey = 2 << 3
  1139  		buf.WriteByte(pbKey)
  1140  		if mp.EOF <= 0b0111_1111 {
  1141  			buf.WriteByte(mp.EOF)
  1142  		} else {
  1143  			buf.WriteByte(0b1000_0000 | (mp.EOF & 0x7F))
  1144  			buf.WriteByte(mp.EOF >> 7)
  1145  		}
  1146  	}
  1147  
  1148  	// field 3
  1149  	if len(mp.Bytes) != 0 {
  1150  		const pbKey = 3<<3 | 2
  1151  		buf.WriteByte(pbKey)
  1152  		err = amino.EncodeUvarintToBuffer(buf, uint64(len(mp.Bytes)))
  1153  		if err != nil {
  1154  			return err
  1155  		}
  1156  		buf.Write(mp.Bytes)
  1157  	}
  1158  
  1159  	return nil
  1160  }
  1161  
  1162  func (mp *PacketMsg) UnmarshalFromAmino(_ *amino.Codec, data []byte) error {
  1163  	var dataLen uint64 = 0
  1164  	var subData []byte
  1165  
  1166  	for {
  1167  		data = data[dataLen:]
  1168  
  1169  		if len(data) == 0 {
  1170  			break
  1171  		}
  1172  
  1173  		pos, aminoType, err := amino.ParseProtoPosAndTypeMustOneByte(data[0])
  1174  		if err != nil {
  1175  			return err
  1176  		}
  1177  		data = data[1:]
  1178  
  1179  		if aminoType == amino.Typ3_ByteLength {
  1180  			var n int
  1181  			dataLen, n, err = amino.DecodeUvarint(data)
  1182  			if err != nil {
  1183  				return err
  1184  			}
  1185  
  1186  			data = data[n:]
  1187  			if len(data) < int(dataLen) {
  1188  				return errors.New("invalid data len")
  1189  			}
  1190  			subData = data[:dataLen]
  1191  		}
  1192  
  1193  		switch pos {
  1194  		case 1:
  1195  			vari, n, err := amino.DecodeUvarint(data)
  1196  			if err != nil {
  1197  				return err
  1198  			}
  1199  			mp.ChannelID = byte(vari)
  1200  			dataLen = uint64(n)
  1201  		case 2:
  1202  			vari, n, err := amino.DecodeUvarint(data)
  1203  			if err != nil {
  1204  				return err
  1205  			}
  1206  			mp.EOF = byte(vari)
  1207  			dataLen = uint64(n)
  1208  		case 3:
  1209  			if cap(mp.Bytes) >= len(subData) {
  1210  				mp.Bytes = mp.Bytes[:len(subData)]
  1211  			} else {
  1212  				mp.Bytes = make([]byte, len(subData))
  1213  			}
  1214  			copy(mp.Bytes, subData)
  1215  		}
  1216  	}
  1217  	return nil
  1218  }
  1219  
  1220  var (
  1221  	PacketPingTypePrefix = []byte{0x15, 0xC3, 0xD2, 0x89}
  1222  	PacketPongTypePrefix = []byte{0x8A, 0x79, 0x7F, 0xE2}
  1223  	PacketMsgTypePrefix  = []byte{0xB0, 0x5B, 0x4F, 0x2C}
  1224  
  1225  	packetPing Packet = PacketPing{}
  1226  	packetPong Packet = PacketPong{}
  1227  
  1228  	packetBzPool = &sync.Pool{
  1229  		New: func() interface{} {
  1230  			return new(bytes.Buffer)
  1231  		},
  1232  	}
  1233  	packetLengthPrefixBzPool = &sync.Pool{
  1234  		New: func() interface{} {
  1235  			return &[binary.MaxVarintLen64]byte{}
  1236  		},
  1237  	}
  1238  )
  1239  
  1240  func unmarshalPacketFromAminoReader(r io.Reader, maxSize int64, targetMsg *PacketMsg) (packet Packet, n int64, err error) {
  1241  	if maxSize < 0 {
  1242  		panic("maxSize cannot be negative.")
  1243  	}
  1244  
  1245  	// Read byte-length prefix.
  1246  	var l int64
  1247  	var buf = packetLengthPrefixBzPool.Get().(*[binary.MaxVarintLen64]byte)
  1248  	defer packetLengthPrefixBzPool.Put(buf)
  1249  	for i := 0; i < len(buf); i++ {
  1250  		_, err = r.Read(buf[i : i+1])
  1251  		if err != nil {
  1252  			return
  1253  		}
  1254  		n += 1
  1255  		if buf[i]&0x80 == 0 {
  1256  			break
  1257  		}
  1258  		if n >= maxSize {
  1259  			err = fmt.Errorf("Read overflow, maxSize is %v but uvarint(length-prefix) is itself greater than maxSize.", maxSize)
  1260  		}
  1261  	}
  1262  	u64, _ := binary.Uvarint(buf[:])
  1263  	if err != nil {
  1264  		return
  1265  	}
  1266  	if maxSize > 0 {
  1267  		if uint64(maxSize) < u64 {
  1268  			err = fmt.Errorf("Read overflow, maxSize is %v but this amino binary object is %v bytes.", maxSize, u64)
  1269  			return
  1270  		}
  1271  		if (maxSize - n) < int64(u64) {
  1272  			err = fmt.Errorf("Read overflow, maxSize is %v but this length-prefixed amino binary object is %v+%v bytes.", maxSize, n, u64)
  1273  			return
  1274  		}
  1275  	}
  1276  	l = int64(u64)
  1277  	if l < 0 {
  1278  		err = fmt.Errorf("Read overflow, this implementation can't read this because, why would anyone have this much data? Hello from 2018.")
  1279  	}
  1280  
  1281  	bbuf := packetBzPool.Get().(*bytes.Buffer)
  1282  	defer packetBzPool.Put(bbuf)
  1283  	bbuf.Grow(int(l))
  1284  	var bz = bbuf.Bytes()
  1285  	if int64(cap(bz)) >= l {
  1286  		bz = bz[:l]
  1287  	} else {
  1288  		bz = make([]byte, l)
  1289  	}
  1290  
  1291  	// Read that many bytes.
  1292  	_, err = io.ReadFull(r, bz)
  1293  	if err != nil {
  1294  		return
  1295  	}
  1296  	n += l
  1297  
  1298  	if bytes.Equal(PacketPingTypePrefix, bz) {
  1299  		packet = packetPing
  1300  		return
  1301  	} else if bytes.Equal(PacketPongTypePrefix, bz) {
  1302  		packet = packetPong
  1303  		return
  1304  	} else if bytes.Equal(PacketMsgTypePrefix, bz[0:4]) {
  1305  		var msg *PacketMsg
  1306  		if targetMsg != nil {
  1307  			msg = targetMsg
  1308  			msg.Reset()
  1309  		} else {
  1310  			msg = &PacketMsg{}
  1311  		}
  1312  		err = msg.UnmarshalFromAmino(cdc, bz[4:])
  1313  		if err == nil {
  1314  			packet = msg
  1315  			return
  1316  		}
  1317  	}
  1318  	var packet4amino Packet
  1319  	err = cdc.UnmarshalBinaryBare(bz, &packet4amino)
  1320  	packet = packet4amino
  1321  	return
  1322  }