revert back to Jae's original payload size limit

except now we calculate the max size using the maxPacketMsgSize()
function, which frees developers from having to know amino encoding
details.

plus, 10 additional bytes are added to leave the room for amino upgrades
(both making it more efficient / less efficient)
This commit is contained in:
Anton Kaliaev 2018-06-29 12:17:26 +04:00
parent ab04201c3d
commit 61c5791fa3
No known key found for this signature in database
GPG Key ID: 7B6881D965918214
15 changed files with 73 additions and 84 deletions

View File

@ -6,8 +6,8 @@ import (
"github.com/tendermint/go-amino" "github.com/tendermint/go-amino"
"github.com/tendermint/tendermint/crypto"
proto "github.com/tendermint/tendermint/benchmarks/proto" proto "github.com/tendermint/tendermint/benchmarks/proto"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/p2p" "github.com/tendermint/tendermint/p2p"
ctypes "github.com/tendermint/tendermint/rpc/core/types" ctypes "github.com/tendermint/tendermint/rpc/core/types"
) )

View File

@ -299,9 +299,8 @@ type P2PConfig struct {
// Time to wait before flushing messages out on the connection, in ms // Time to wait before flushing messages out on the connection, in ms
FlushThrottleTimeout int `mapstructure:"flush_throttle_timeout"` FlushThrottleTimeout int `mapstructure:"flush_throttle_timeout"`
// Maximum size of a message packet, in bytes // Maximum size of a message packet payload, in bytes
// Includes a header, which is ~13 bytes MaxPacketMsgPayloadSize int `mapstructure:"max_packet_msg_payload_size"`
MaxPacketMsgSize int `mapstructure:"max_packet_msg_size"`
// Rate at which packets can be sent, in bytes/second // Rate at which packets can be sent, in bytes/second
SendRate int64 `mapstructure:"send_rate"` SendRate int64 `mapstructure:"send_rate"`
@ -346,7 +345,7 @@ func DefaultP2PConfig() *P2PConfig {
AddrBookStrict: true, AddrBookStrict: true,
MaxNumPeers: 50, MaxNumPeers: 50,
FlushThrottleTimeout: 100, FlushThrottleTimeout: 100,
MaxPacketMsgSize: 1024, // 1 kB MaxPacketMsgPayloadSize: 1024, // 1 kB
SendRate: 512000, // 500 kB/s SendRate: 512000, // 500 kB/s
RecvRate: 512000, // 500 kB/s RecvRate: 512000, // 500 kB/s
PexReactor: true, PexReactor: true,

View File

@ -164,9 +164,8 @@ flush_throttle_timeout = {{ .P2P.FlushThrottleTimeout }}
# Maximum number of peers to connect to # Maximum number of peers to connect to
max_num_peers = {{ .P2P.MaxNumPeers }} max_num_peers = {{ .P2P.MaxNumPeers }}
# Maximum size of a message packet, in bytes # Maximum size of a message packet payload, in bytes
# Includes a header, which is ~13 bytes max_packet_msg_payload_size = {{ .P2P.MaxPacketMsgPayloadSize }}
max_packet_msg_size = {{ .P2P.MaxPacketMsgSize }}
# Rate at which packets can be sent, in bytes/second # Rate at which packets can be sent, in bytes/second
send_rate = {{ .P2P.SendRate }} send_rate = {{ .P2P.SendRate }}

View File

@ -6,8 +6,8 @@ import (
cmn "github.com/tendermint/tmlibs/common" cmn "github.com/tendermint/tmlibs/common"
. "github.com/tendermint/tmlibs/test" . "github.com/tendermint/tmlibs/test"
"testing"
"github.com/tendermint/tendermint/crypto/tmhash" "github.com/tendermint/tendermint/crypto/tmhash"
"testing"
) )
type testItem []byte type testItem []byte

View File

@ -21,7 +21,7 @@ to prevent Denial-of-service attacks. You can read more about it
### P2P ### P2P
The core of the Tendermint peer-to-peer system is `MConnection`. Each The core of the Tendermint peer-to-peer system is `MConnection`. Each
connection has `MaxPacketMsgSize`, which is the maximum packet connection has `MaxPacketMsgPayloadSize`, which is the maximum packet
size and bounded send & receive queues. One can impose restrictions on size and bounded send & receive queues. One can impose restrictions on
send & receive rate per connection (`SendRate`, `RecvRate`). send & receive rate per connection (`SendRate`, `RecvRate`).

View File

@ -119,7 +119,7 @@ flush_throttle_timeout = 100
max_num_peers = 50 max_num_peers = 50
# Maximum size of a message packet payload, in bytes # Maximum size of a message packet payload, in bytes
max_msg_packet_payload_size = 1024 max_packet_msg_payload_size = 1024
# Rate at which packets can be sent, in bytes/second # Rate at which packets can be sent, in bytes/second
send_rate = 512000 send_rate = 512000

View File

@ -2,8 +2,8 @@ package evidence
import ( import (
"github.com/tendermint/go-amino" "github.com/tendermint/go-amino"
"github.com/tendermint/tendermint/types"
"github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/types"
) )
var cdc = amino.NewCodec() var cdc = amino.NewCodec()

View File

@ -18,7 +18,7 @@ import (
) )
const ( const (
defaultMaxPacketMsgSize = 1024 defaultMaxPacketMsgPayloadSize = 1024
numBatchPacketMsgs = 10 numBatchPacketMsgs = 10
minReadBufferSize = 1024 minReadBufferSize = 1024
@ -96,7 +96,7 @@ type MConnection struct {
created time.Time // time of creation created time.Time // time of creation
emptyPacketMsgSize int _maxPacketMsgSize int
} }
// MConnConfig is a MConnection configuration. // MConnConfig is a MConnection configuration.
@ -105,7 +105,7 @@ type MConnConfig struct {
RecvRate int64 `mapstructure:"recv_rate"` RecvRate int64 `mapstructure:"recv_rate"`
// Maximum payload size // Maximum payload size
MaxPacketMsgSize int `mapstructure:"max_packet_msg_size"` MaxPacketMsgPayloadSize int `mapstructure:"max_packet_msg_payload_size"`
// Interval to flush writes (throttled) // Interval to flush writes (throttled)
FlushThrottle time.Duration `mapstructure:"flush_throttle"` FlushThrottle time.Duration `mapstructure:"flush_throttle"`
@ -122,7 +122,7 @@ func DefaultMConnConfig() MConnConfig {
return MConnConfig{ return MConnConfig{
SendRate: defaultSendRate, SendRate: defaultSendRate,
RecvRate: defaultRecvRate, RecvRate: defaultRecvRate,
MaxPacketMsgSize: defaultMaxPacketMsgSize, MaxPacketMsgPayloadSize: defaultMaxPacketMsgPayloadSize,
FlushThrottle: defaultFlushThrottle, FlushThrottle: defaultFlushThrottle,
PingInterval: defaultPingInterval, PingInterval: defaultPingInterval,
PongTimeout: defaultPongTimeout, PongTimeout: defaultPongTimeout,
@ -156,7 +156,6 @@ func NewMConnectionWithConfig(conn net.Conn, chDescs []*ChannelDescriptor, onRec
onReceive: onReceive, onReceive: onReceive,
onError: onError, onError: onError,
config: config, config: config,
emptyPacketMsgSize: emptyPacketMsgSize(config.MaxPacketMsgSize),
} }
// Create channels // Create channels
@ -173,6 +172,9 @@ func NewMConnectionWithConfig(conn net.Conn, chDescs []*ChannelDescriptor, onRec
mconn.BaseService = *cmn.NewBaseService(nil, "MConnection", mconn) mconn.BaseService = *cmn.NewBaseService(nil, "MConnection", mconn)
// maxPacketMsgSize() is a bit heavy, so call just once
mconn._maxPacketMsgSize = mconn.maxPacketMsgSize()
return mconn return mconn
} }
@ -397,7 +399,7 @@ func (c *MConnection) sendSomePacketMsgs() bool {
// Block until .sendMonitor says we can write. // Block until .sendMonitor says we can write.
// Once we're ready we send more than we asked for, // Once we're ready we send more than we asked for,
// but amortized it should even out. // but amortized it should even out.
c.sendMonitor.Limit(c.config.MaxPacketMsgSize, atomic.LoadInt64(&c.config.SendRate), true) c.sendMonitor.Limit(c._maxPacketMsgSize, atomic.LoadInt64(&c.config.SendRate), true)
// Now send some PacketMsgs. // Now send some PacketMsgs.
for i := 0; i < numBatchPacketMsgs; i++ { for i := 0; i < numBatchPacketMsgs; i++ {
@ -455,7 +457,7 @@ func (c *MConnection) recvRoutine() {
FOR_LOOP: FOR_LOOP:
for { for {
// Block until .recvMonitor says we can read. // Block until .recvMonitor says we can read.
c.recvMonitor.Limit(c.config.MaxPacketMsgSize, atomic.LoadInt64(&c.config.RecvRate), true) c.recvMonitor.Limit(c._maxPacketMsgSize, atomic.LoadInt64(&c.config.RecvRate), true)
// Peek into bufConnReader for debugging // Peek into bufConnReader for debugging
/* /*
@ -475,7 +477,7 @@ FOR_LOOP:
var packet Packet var packet Packet
var _n int64 var _n int64
var err error var err error
_n, err = cdc.UnmarshalBinaryReader(c.bufConnReader, &packet, int64(c.config.MaxPacketMsgSize)) _n, err = cdc.UnmarshalBinaryReader(c.bufConnReader, &packet, int64(c._maxPacketMsgSize))
c.recvMonitor.Update(int(_n)) c.recvMonitor.Update(int(_n))
if err != nil { if err != nil {
if c.IsRunning() { if c.IsRunning() {
@ -548,6 +550,16 @@ func (c *MConnection) stopPongTimer() {
} }
} }
// maxPacketMsgSize returns a maximum size of PacketMsg, including the overhead
// of amino encoding.
func (c *MConnection) maxPacketMsgSize() int {
return len(cdc.MustMarshalBinary(PacketMsg{
ChannelID: 0x01,
EOF: 1,
Bytes: make([]byte, c.config.MaxPacketMsgPayloadSize),
})) + 10 // leave room for changes in amino
}
type ConnectionStatus struct { type ConnectionStatus struct {
Duration time.Duration Duration time.Duration
SendMonitor flow.Status SendMonitor flow.Status
@ -631,7 +643,7 @@ func newChannel(conn *MConnection, desc ChannelDescriptor) *Channel {
desc: desc, desc: desc,
sendQueue: make(chan []byte, desc.SendQueueCapacity), sendQueue: make(chan []byte, desc.SendQueueCapacity),
recving: make([]byte, 0, desc.RecvBufferCapacity), recving: make([]byte, 0, desc.RecvBufferCapacity),
maxPacketMsgPayloadSize: conn.config.MaxPacketMsgSize - conn.emptyPacketMsgSize, maxPacketMsgPayloadSize: conn.config.MaxPacketMsgPayloadSize,
} }
} }
@ -780,24 +792,3 @@ type PacketMsg struct {
func (mp PacketMsg) String() string { func (mp PacketMsg) String() string {
return fmt.Sprintf("PacketMsg{%X:%X T:%X}", mp.ChannelID, mp.Bytes, mp.EOF) return fmt.Sprintf("PacketMsg{%X:%X T:%X}", mp.ChannelID, mp.Bytes, mp.EOF)
} }
// - Uvarint length of MustMarshalBinary(packet) = 1 or 2 bytes
// (as long as it's less than 16,384 bytes)
// - Prefix bytes = 4 bytes
// - ChannelID field key + byte = 2 bytes
// - EOF field key + byte = 2 bytes
// - Bytes field key = 1 bytes
// - Uvarint length of MustMarshalBinary(bytes) = 1 or 2 bytes
// = up to 13 bytes overhead for the packet.
func emptyPacketMsgSize(maxPayloadSize int) int {
emptyPacketMsgSize := len(cdc.MustMarshalBinary(PacketMsg{
ChannelID: 0x01,
EOF: 1,
Bytes: make([]byte, maxPayloadSize),
}))
// -1 byte of data
// +1 byte because uvarint length of MustMarshalBinary(bytes) will be 2 bytes for big packets
// +1 byte because uvarint length of MustMarshalBinary(packet) will be 2 bytes for big packets
return emptyPacketMsgSize - maxPayloadSize + 1 + 1
}

View File

@ -426,7 +426,7 @@ func TestMConnectionReadErrorLongMessage(t *testing.T) {
var packet = PacketMsg{ var packet = PacketMsg{
ChannelID: 0x01, ChannelID: 0x01,
EOF: 1, EOF: 1,
Bytes: make([]byte, mconnClient.config.MaxPacketMsgSize-emptyPacketMsgSize(mconnClient.config.MaxPacketMsgSize)), Bytes: make([]byte, mconnClient.config.MaxPacketMsgPayloadSize),
} }
_, err = cdc.MarshalBinaryWriter(buf, packet) _, err = cdc.MarshalBinaryWriter(buf, packet)
assert.Nil(t, err) assert.Nil(t, err)
@ -440,7 +440,7 @@ func TestMConnectionReadErrorLongMessage(t *testing.T) {
packet = PacketMsg{ packet = PacketMsg{
ChannelID: 0x01, ChannelID: 0x01,
EOF: 1, EOF: 1,
Bytes: make([]byte, mconnClient.config.MaxPacketMsgSize+1), Bytes: make([]byte, mconnClient.config.MaxPacketMsgPayloadSize+100),
} }
_, err = cdc.MarshalBinaryWriter(buf, packet) _, err = cdc.MarshalBinaryWriter(buf, packet)
assert.Nil(t, err) assert.Nil(t, err)

View File

@ -100,7 +100,7 @@ func NewSwitch(cfg *config.P2PConfig, options ...SwitchOption) *Switch {
mConfig.FlushThrottle = time.Duration(cfg.FlushThrottleTimeout) * time.Millisecond mConfig.FlushThrottle = time.Duration(cfg.FlushThrottleTimeout) * time.Millisecond
mConfig.SendRate = cfg.SendRate mConfig.SendRate = cfg.SendRate
mConfig.RecvRate = cfg.RecvRate mConfig.RecvRate = cfg.RecvRate
mConfig.MaxPacketMsgSize = cfg.MaxPacketMsgSize mConfig.MaxPacketMsgPayloadSize = cfg.MaxPacketMsgPayloadSize
sw.mConfig = mConfig sw.mConfig = mConfig

View File

@ -9,8 +9,8 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/types"
"github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/types"
cmn "github.com/tendermint/tmlibs/common" cmn "github.com/tendermint/tmlibs/common"
) )

View File

@ -3,8 +3,8 @@ package core
import ( import (
"time" "time"
crypto "github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/consensus" "github.com/tendermint/tendermint/consensus"
crypto "github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/p2p" "github.com/tendermint/tendermint/p2p"
"github.com/tendermint/tendermint/proxy" "github.com/tendermint/tendermint/proxy"
sm "github.com/tendermint/tendermint/state" sm "github.com/tendermint/tendermint/state"