evidence: use bytes instead of quantity to limit size (#5449)(#5476)

This commit is contained in:
Callum Waters
2020-10-08 14:38:11 +02:00
committed by GitHub
parent dac18d73a7
commit 7d5d417dc9
26 changed files with 227 additions and 274 deletions
+2 -2
View File
@@ -100,10 +100,10 @@ func (blockExec *BlockExecutor) CreateProposalBlock(
maxBytes := state.ConsensusParams.Block.MaxBytes
maxGas := state.ConsensusParams.Block.MaxGas
evidence := blockExec.evpool.PendingEvidence(state.ConsensusParams.Evidence.MaxNum)
evidence, evSize := blockExec.evpool.PendingEvidence(state.ConsensusParams.Evidence.MaxBytes)
// Fetch a limited amount of valid txs
maxDataBytes := types.MaxDataBytes(maxBytes, state.Validators.Size(), len(evidence))
maxDataBytes := types.MaxDataBytes(maxBytes, evSize, state.Validators.Size())
txs := blockExec.mempool.ReapMaxBytesMaxGas(maxDataBytes, maxGas)
return state.MakeBlock(height, txs, commit, evidence, proposerAddr)
+10 -3
View File
@@ -61,11 +61,11 @@ func (_m *EvidencePool) CheckEvidence(_a0 types.EvidenceList) error {
}
// PendingEvidence provides a mock function with given fields: _a0
func (_m *EvidencePool) PendingEvidence(_a0 uint32) []types.Evidence {
func (_m *EvidencePool) PendingEvidence(_a0 int64) ([]types.Evidence, int64) {
ret := _m.Called(_a0)
var r0 []types.Evidence
if rf, ok := ret.Get(0).(func(uint32) []types.Evidence); ok {
if rf, ok := ret.Get(0).(func(int64) []types.Evidence); ok {
r0 = rf(_a0)
} else {
if ret.Get(0) != nil {
@@ -73,7 +73,14 @@ func (_m *EvidencePool) PendingEvidence(_a0 uint32) []types.Evidence {
}
}
return r0
var r1 int64
if rf, ok := ret.Get(1).(func(int64) int64); ok {
r1 = rf(_a0)
} else {
r1 = ret.Get(1).(int64)
}
return r0, r1
}
// Update provides a mock function with given fields: _a0
+4 -2
View File
@@ -43,7 +43,7 @@ type BlockStore interface {
// EvidencePool defines the EvidencePool interface used by State.
type EvidencePool interface {
PendingEvidence(uint32) []types.Evidence
PendingEvidence(maxBytes int64) (ev []types.Evidence, size int64)
AddEvidence(types.Evidence) error
Update(State)
CheckEvidence(types.EvidenceList) error
@@ -54,7 +54,9 @@ type EvidencePool interface {
// to the consensus evidence pool interface
type EmptyEvidencePool struct{}
func (EmptyEvidencePool) PendingEvidence(uint32) []types.Evidence { return nil }
func (EmptyEvidencePool) PendingEvidence(maxBytes int64) (ev []types.Evidence, size int64) {
return nil, 0
}
func (EmptyEvidencePool) AddEvidence(types.Evidence) error { return nil }
func (EmptyEvidencePool) Update(State) {}
func (EmptyEvidencePool) CheckEvidence(evList types.EvidenceList) error { return nil }
+1 -2
View File
@@ -8,10 +8,9 @@ import (
// TxPreCheck returns a function to filter transactions before processing.
// The function limits the size of a transaction to the block's maximum data size.
func TxPreCheck(state State) mempl.PreCheckFunc {
maxDataBytes := types.MaxDataBytesUnknownEvidence(
maxDataBytes := types.MaxDataBytesNoEvidence(
state.ConsensusParams.Block.MaxBytes,
state.Validators.Size(),
state.ConsensusParams.Evidence.MaxNum,
)
return mempl.PreCheckMaxBytes(maxDataBytes)
}
+3 -3
View File
@@ -17,7 +17,7 @@ import (
func TestTxFilter(t *testing.T) {
genDoc := randomGenesisDoc()
genDoc.ConsensusParams.Block.MaxBytes = 3000
genDoc.ConsensusParams.Evidence.MaxNum = 1
genDoc.ConsensusParams.Evidence.MaxBytes = 1500
// Max size of Txs is much smaller than size of block,
// since we need to account for commits and evidence.
@@ -25,8 +25,8 @@ func TestTxFilter(t *testing.T) {
tx types.Tx
isErr bool
}{
{types.Tx(tmrand.Bytes(1680)), false},
{types.Tx(tmrand.Bytes(1853)), true},
{types.Tx(tmrand.Bytes(2154)), false},
{types.Tx(tmrand.Bytes(2155)), true},
{types.Tx(tmrand.Bytes(3000)), true},
}
+2 -2
View File
@@ -142,8 +142,8 @@ func validateBlock(evidencePool EvidencePool, state State, block *types.Block) e
block.Height, state.InitialHeight)
}
// Check evidence doesn't exceed the limit. MaxNumEvidence is capped at uint16, so conversion is always safe.
if max, got := int(state.ConsensusParams.Evidence.MaxNum), len(block.Evidence.Evidence); got > max {
// Check evidence doesn't exceed the limit amount of bytes.
if max, got := state.ConsensusParams.Evidence.MaxBytes, block.Evidence.ByteSize(); got > max {
return types.NewErrEvidenceOverflow(max, got)
}
+18 -13
View File
@@ -222,7 +222,7 @@ func TestValidateBlockEvidence(t *testing.T) {
evpool.On("ABCIEvidence", mock.AnythingOfType("int64"), mock.AnythingOfType("[]types.Evidence")).Return(
[]abci.Evidence{})
state.ConsensusParams.Evidence.MaxNum = 3
state.ConsensusParams.Evidence.MaxBytes = 1000
blockExec := sm.NewBlockExecutor(
stateStore,
log.TestingLogger(),
@@ -234,17 +234,19 @@ func TestValidateBlockEvidence(t *testing.T) {
for height := int64(1); height < validationTestsStopHeight; height++ {
proposerAddr := state.Validators.GetProposer().Address
maxNumEvidence := state.ConsensusParams.Evidence.MaxNum
maxBytesEvidence := state.ConsensusParams.Evidence.MaxBytes
if height > 1 {
/*
A block with too much evidence fails
*/
require.True(t, maxNumEvidence > 2)
evidence := make([]types.Evidence, 0)
// one more than the maximum allowed evidence
for i := uint32(0); i <= maxNumEvidence; i++ {
evidence = append(evidence, types.NewMockDuplicateVoteEvidenceWithValidator(height, time.Now(),
privVals[proposerAddr.String()], chainID))
var currentBytes int64 = 0
// more bytes than the maximum allowed for evidence
for currentBytes <= maxBytesEvidence {
newEv := types.NewMockDuplicateVoteEvidenceWithValidator(height, time.Now(),
privVals[proposerAddr.String()], chainID)
evidence = append(evidence, newEv)
currentBytes += int64(len(newEv.Bytes()))
}
block, _ := state.MakeBlock(height, makeTxs(height), lastCommit, evidence, proposerAddr)
err := blockExec.ValidateBlock(state, block)
@@ -257,14 +259,17 @@ func TestValidateBlockEvidence(t *testing.T) {
/*
A good block with several pieces of good evidence passes
*/
require.True(t, maxNumEvidence > 2)
evidence := make([]types.Evidence, 0)
var currentBytes int64 = 0
// precisely the amount of allowed evidence
for i := int32(0); uint32(i) < maxNumEvidence; i++ {
// make different evidence for each validator
_, val := state.Validators.GetByIndex(i)
evidence = append(evidence, types.NewMockDuplicateVoteEvidenceWithValidator(height, defaultEvidenceTime,
privVals[val.Address.String()], chainID))
for {
newEv := types.NewMockDuplicateVoteEvidenceWithValidator(height, defaultEvidenceTime,
privVals[proposerAddr.String()], chainID)
currentBytes += int64(len(newEv.Bytes()))
if currentBytes >= maxBytesEvidence {
break
}
evidence = append(evidence, newEv)
}
var err error