backport block size fixes (#5492)

* mempool: length prefix txs when getting them from mempool (#5483)

* correctly calculate evidence data size (#5482)

* block: use commit sig size instead of vote size (#5490)

* tx: reduce function to one parameter (#5493)
This commit is contained in:
Marko
2020-10-13 18:07:54 +02:00
committed by GitHub
parent 7d5d417dc9
commit 09982ae407
17 changed files with 320 additions and 454 deletions
+26 -33
View File
@@ -277,7 +277,7 @@ func MaxDataBytes(maxBytes, evidenceBytes int64, valsCount int) int64 {
maxDataBytes := maxBytes -
MaxOverheadForBlock -
MaxHeaderBytes -
int64(valsCount)*MaxVoteBytes -
MaxCommitBytes(valsCount) -
evidenceBytes
if maxDataBytes < 0 {
@@ -289,7 +289,6 @@ func MaxDataBytes(maxBytes, evidenceBytes int64, valsCount int) int64 {
}
return maxDataBytes
}
// MaxDataBytesNoEvidence returns the maximum size of block's data when
@@ -301,7 +300,7 @@ func MaxDataBytesNoEvidence(maxBytes int64, valsCount int) int64 {
maxDataBytes := maxBytes -
MaxOverheadForBlock -
MaxHeaderBytes -
int64(valsCount)*MaxVoteBytes
MaxCommitBytes(valsCount)
if maxDataBytes < 0 {
panic(fmt.Sprintf(
@@ -581,6 +580,14 @@ const (
BlockIDFlagNil
)
const (
// Max size of commit without any commitSigs -> 82 for BlockID, 8 for Height, 4 for Round.
MaxCommitOverheadBytes int64 = 94
// Commit sig size is made up of 32 bytes for the signature, 20 bytes for the address,
// 1 byte for the flag and 14 bytes for the timestamp
MaxCommitSigBytes int64 = 77
)
// CommitSig is a part of the Vote included in a Commit.
type CommitSig struct {
BlockIDFlag BlockIDFlag `json:"block_id_flag"`
@@ -599,9 +606,10 @@ func NewCommitSigForBlock(signature []byte, valAddr Address, ts time.Time) Commi
}
}
// ForBlock returns true if CommitSig is for the block.
func (cs CommitSig) ForBlock() bool {
return cs.BlockIDFlag == BlockIDFlagCommit
func MaxCommitBytes(valCount int) int64 {
// From the repeated commit sig field
var protoEncodingOverhead int64 = 2
return MaxCommitOverheadBytes + ((MaxCommitSigBytes + protoEncodingOverhead) * int64(valCount))
}
// NewCommitSigAbsent returns new CommitSig with BlockIDFlagAbsent. Other
@@ -612,6 +620,11 @@ func NewCommitSigAbsent() CommitSig {
}
}
// ForBlock returns true if CommitSig is for the block.
func (cs CommitSig) ForBlock() bool {
return cs.BlockIDFlag == BlockIDFlagCommit
}
// Absent returns true if CommitSig is absent.
func (cs CommitSig) Absent() bool {
return cs.BlockIDFlag == BlockIDFlagAbsent
@@ -935,10 +948,7 @@ func (commit *Commit) ToProto() *tmproto.Commit {
c.Height = commit.Height
c.Round = commit.Round
c.BlockID = commit.BlockID.ToProto()
if commit.hash != nil {
c.Hash = commit.hash
}
c.BitArray = commit.bitArray.ToProto()
return c
}
@@ -950,8 +960,7 @@ func CommitFromProto(cp *tmproto.Commit) (*Commit, error) {
}
var (
commit = new(Commit)
bitArray *bits.BitArray
commit = new(Commit)
)
bi, err := BlockIDFromProto(&cp.BlockID)
@@ -959,8 +968,6 @@ func CommitFromProto(cp *tmproto.Commit) (*Commit, error) {
return nil, err
}
bitArray.FromProto(cp.BitArray)
sigs := make([]CommitSig, len(cp.Signatures))
for i := range cp.Signatures {
if err := sigs[i].FromProto(cp.Signatures[i]); err != nil {
@@ -972,8 +979,6 @@ func CommitFromProto(cp *tmproto.Commit) (*Commit, error) {
commit.Height = cp.Height
commit.Round = cp.Round
commit.BlockID = *bi
commit.hash = cp.Hash
commit.bitArray = bitArray
return commit, commit.ValidateBasic()
}
@@ -1035,10 +1040,6 @@ func (data *Data) ToProto() tmproto.Data {
tp.Txs = txBzs
}
if data.hash != nil {
tp.Hash = data.hash
}
return *tp
}
@@ -1060,8 +1061,6 @@ func DataFromProto(dp *tmproto.Data) (Data, error) {
data.Txs = Txs{}
}
data.hash = dp.Hash
return *data, nil
}
@@ -1087,13 +1086,11 @@ func (data *EvidenceData) Hash() tmbytes.HexBytes {
// ByteSize returns the total byte size of all the evidence
func (data *EvidenceData) ByteSize() int64 {
if data.byteSize == 0 && len(data.Evidence) != 0 {
for _, ev := range data.Evidence {
pb, err := EvidenceToProto(ev)
if err != nil {
panic(err)
}
data.byteSize += int64(pb.Size())
pb, err := data.ToProto()
if err != nil {
panic(err)
}
data.byteSize = int64(pb.Size())
}
return data.byteSize
}
@@ -1135,10 +1132,6 @@ func (data *EvidenceData) ToProto() (*tmproto.EvidenceData, error) {
}
evi.Evidence = eviBzs
if data.hash != nil {
evi.Hash = data.hash
}
return evi, nil
}
@@ -1155,9 +1148,9 @@ func (data *EvidenceData) FromProto(eviData *tmproto.EvidenceData) error {
return err
}
eviBzs[i] = evi
data.byteSize += int64(eviData.Evidence[i].Size())
}
data.Evidence = eviBzs
data.byteSize = int64(eviData.Size())
return nil
}
+62 -8
View File
@@ -257,6 +257,62 @@ func TestCommitValidateBasic(t *testing.T) {
}
}
func TestMaxCommitSigBytes(t *testing.T) {
// time is varint encoded so need to pick the max.
// year int, month Month, day, hour, min, sec, nsec int, loc *Location
timestamp := time.Date(math.MaxInt64, 0, 0, 0, 0, 0, math.MaxInt64, time.UTC)
cs := &CommitSig{
BlockIDFlag: BlockIDFlagNil,
ValidatorAddress: crypto.AddressHash([]byte("validator_address")),
Timestamp: timestamp,
Signature: tmhash.Sum([]byte("signature")),
}
pb := cs.ToProto()
assert.EqualValues(t, MaxCommitSigBytes, pb.Size())
}
func TestMaxCommitBytes(t *testing.T) {
timestamp := time.Date(math.MaxInt64, 0, 0, 0, 0, 0, math.MaxInt64, time.UTC)
cs := CommitSig{
BlockIDFlag: BlockIDFlagNil,
ValidatorAddress: crypto.AddressHash([]byte("validator_address")),
Timestamp: timestamp,
Signature: tmhash.Sum([]byte("signature")),
}
// check size with a single commit
commit := &Commit{
Height: math.MaxInt64,
Round: math.MaxInt32,
BlockID: BlockID{
Hash: tmhash.Sum([]byte("blockID_hash")),
PartSetHeader: PartSetHeader{
Total: math.MaxInt32,
Hash: tmhash.Sum([]byte("blockID_part_set_header_hash")),
},
},
Signatures: []CommitSig{cs},
}
pb := commit.ToProto()
assert.EqualValues(t, MaxCommitBytes(1), int64(pb.Size()))
// check the upper bound of the commit size
for i := 1; i < MaxVotesCount; i++ {
commit.Signatures = append(commit.Signatures, cs)
}
pb = commit.ToProto()
assert.EqualValues(t, MaxCommitBytes(MaxVotesCount), int64(pb.Size()))
}
func TestHeaderHash(t *testing.T) {
testCases := []struct {
desc string
@@ -407,9 +463,9 @@ func TestBlockMaxDataBytes(t *testing.T) {
}{
0: {-10, 1, 0, true, 0},
1: {10, 1, 0, true, 0},
2: {844, 1, 0, true, 0},
3: {846, 1, 0, false, 0},
4: {847, 1, 0, false, 1},
2: {809, 1, 0, true, 0},
3: {810, 1, 0, false, 0},
4: {811, 1, 0, false, 1},
}
for i, tc := range testCases {
@@ -436,9 +492,9 @@ func TestBlockMaxDataBytesNoEvidence(t *testing.T) {
}{
0: {-10, 1, true, 0},
1: {10, 1, true, 0},
2: {845, 1, true, 0},
3: {846, 1, false, 0},
4: {847, 1, false, 1},
2: {809, 1, true, 0},
3: {810, 1, false, 0},
4: {811, 1, false, 1},
}
for i, tc := range testCases {
@@ -628,9 +684,7 @@ func TestBlockProtoBuf(t *testing.T) {
func TestDataProtoBuf(t *testing.T) {
data := &Data{Txs: Txs{Tx([]byte{1}), Tx([]byte{2}), Tx([]byte{3})}}
_ = data.Hash()
data2 := &Data{Txs: Txs{}}
_ = data2.Hash()
testCases := []struct {
msg string
data1 *Data
+8
View File
@@ -137,3 +137,11 @@ func TxProofFromProto(pb tmproto.TxProof) (TxProof, error) {
return pbtp, nil
}
// ComputeProtoSizeForTxs wraps the transactions in tmproto.Data{} and calculates the size.
// https://developers.google.com/protocol-buffers/docs/encoding
func ComputeProtoSizeForTxs(txs []Tx) int64 {
data := Data{Txs: txs}
pdData := data.ToProto()
return int64(pdData.Size())
}
+1 -3
View File
@@ -13,9 +13,7 @@ import (
)
const (
// MaxVoteBytes is a maximum vote size (including amino overhead).
MaxVoteBytes int64 = 209
nilVoteStr string = "nil-Vote"
nilVoteStr string = "nil-Vote"
)
var (
-33
View File
@@ -1,7 +1,6 @@
package types
import (
"math"
"testing"
"time"
@@ -218,38 +217,6 @@ func TestVoteVerify(t *testing.T) {
}
}
func TestMaxVoteBytes(t *testing.T) {
// time is varint encoded so need to pick the max.
// year int, month Month, day, hour, min, sec, nsec int, loc *Location
timestamp := time.Date(math.MaxInt64, 0, 0, 0, 0, 0, math.MaxInt64, time.UTC)
vote := &Vote{
ValidatorAddress: crypto.AddressHash([]byte("validator_address")),
ValidatorIndex: math.MaxInt32,
Height: math.MaxInt64,
Round: math.MaxInt32,
Timestamp: timestamp,
Type: tmproto.PrevoteType,
BlockID: BlockID{
Hash: tmhash.Sum([]byte("blockID_hash")),
PartSetHeader: PartSetHeader{
Total: math.MaxInt32,
Hash: tmhash.Sum([]byte("blockID_part_set_header_hash")),
},
},
}
v := vote.ToProto()
privVal := NewMockPV()
err := privVal.SignVote("test_chain_id", v)
require.NoError(t, err)
bz, err := proto.Marshal(v)
require.NoError(t, err)
assert.EqualValues(t, MaxVoteBytes, len(bz))
}
func TestVoteString(t *testing.T) {
str := examplePrecommit().String()
expected := `Vote{56789:6AF1F4111082 12345/02/SIGNED_MSG_TYPE_PRECOMMIT(Precommit) 8B01023386C3 000000000000 @ 2017-12-25T03:00:01.234Z}` //nolint:lll //ignore line length for tests