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