Browse Source

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

pull/5501/head
Callum Waters 4 years ago
committed by GitHub
parent
commit
55e8ccab21
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 146 additions and 50 deletions
  1. +62
    -1
      node/node_test.go
  2. +2
    -2
      state/tx_filter_test.go
  3. +19
    -5
      types/block.go
  4. +62
    -6
      types/block_test.go
  5. +1
    -3
      types/vote.go
  6. +0
    -33
      types/vote_test.go

+ 62
- 1
node/node_test.go View File

@ -241,7 +241,7 @@ func TestCreateProposalBlock(t *testing.T) {
proposerAddr, _ := state.Validators.GetByIndex(0)
// Make Mempool
memplMetrics := mempl.PrometheusMetrics("node_test")
memplMetrics := mempl.PrometheusMetrics("node_test_1")
mempool := mempl.NewCListMempool(
config.Mempool,
proxyApp.Mempool(),
@ -309,6 +309,67 @@ func TestCreateProposalBlock(t *testing.T) {
assert.NoError(t, err)
}
func TestMaxProposalBlockSize(t *testing.T) {
config := cfg.ResetTestRoot("node_create_proposal")
defer os.RemoveAll(config.RootDir)
cc := proxy.NewLocalClientCreator(kvstore.NewApplication())
proxyApp := proxy.NewAppConns(cc)
err := proxyApp.Start()
require.Nil(t, err)
defer proxyApp.Stop() //nolint:errcheck // ignore for tests
logger := log.TestingLogger()
var height int64 = 1
state, stateDB, _ := state(1, height)
stateStore := sm.NewStore(stateDB)
var maxBytes int64 = 16384
var partSize uint32 = 256
state.ConsensusParams.Block.MaxBytes = maxBytes
proposerAddr, _ := state.Validators.GetByIndex(0)
// Make Mempool
memplMetrics := mempl.PrometheusMetrics("node_test_2")
mempool := mempl.NewCListMempool(
config.Mempool,
proxyApp.Mempool(),
state.LastBlockHeight,
mempl.WithMetrics(memplMetrics),
mempl.WithPreCheck(sm.TxPreCheck(state)),
mempl.WithPostCheck(sm.TxPostCheck(state)),
)
mempool.SetLogger(logger)
// fill the mempool with one txs just below the maximum size
txLength := int(types.MaxDataBytesNoEvidence(maxBytes, 1))
tx := tmrand.Bytes(txLength - 4) // to account for the varint
err = mempool.CheckTx(tx, nil, mempl.TxInfo{})
assert.NoError(t, err)
blockExec := sm.NewBlockExecutor(
stateStore,
logger,
proxyApp.Consensus(),
mempool,
sm.EmptyEvidencePool{},
)
commit := types.NewCommit(height-1, 0, types.BlockID{}, nil)
block, _ := blockExec.CreateProposalBlock(
height,
state, commit,
proposerAddr,
)
pb, err := block.ToProto()
require.NoError(t, err)
assert.Less(t, int64(pb.Size()), maxBytes)
// check that the part set does not exceed the maximum block size
partSet := block.MakePartSet(partSize)
assert.EqualValues(t, partSet.ByteSize(), int64(pb.Size()))
}
func TestNodeNewNodeCustomReactors(t *testing.T) {
config := cfg.ResetTestRoot("node_new_node_custom_reactors_test")
defer os.RemoveAll(config.RootDir)


+ 2
- 2
state/tx_filter_test.go View File

@ -25,8 +25,8 @@ func TestTxFilter(t *testing.T) {
tx types.Tx
isErr bool
}{
{types.Tx(tmrand.Bytes(2151)), false},
{types.Tx(tmrand.Bytes(2152)), true},
{types.Tx(tmrand.Bytes(2187)), false},
{types.Tx(tmrand.Bytes(2188)), true},
{types.Tx(tmrand.Bytes(3000)), true},
}


+ 19
- 5
types/block.go View File

@ -267,7 +267,7 @@ func MaxDataBytes(maxBytes, evidenceBytes int64, valsCount int) int64 {
maxDataBytes := maxBytes -
MaxOverheadForBlock -
MaxHeaderBytes -
int64(valsCount)*MaxVoteBytes -
MaxCommitBytes(valsCount) -
evidenceBytes
if maxDataBytes < 0 {
@ -290,7 +290,7 @@ func MaxDataBytesNoEvidence(maxBytes int64, valsCount int) int64 {
maxDataBytes := maxBytes -
MaxOverheadForBlock -
MaxHeaderBytes -
int64(valsCount)*MaxVoteBytes
MaxCommitBytes(valsCount)
if maxDataBytes < 0 {
panic(fmt.Sprintf(
@ -570,6 +570,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"`
@ -588,9 +596,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
@ -601,6 +610,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


+ 62
- 6
types/block_test.go View File

@ -268,6 +268,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
@ -418,9 +474,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 {
@ -447,9 +503,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 {


+ 1
- 3
types/vote.go 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 (


+ 0
- 33
types/vote_test.go 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


Loading…
Cancel
Save