mirror of
https://github.com/tendermint/tendermint.git
synced 2026-01-10 15:07:24 +00:00
evidence: cap evidence to an absolute number (#4780)
The number of evidence that can be committed in a single block is capped by a new evidence parameter called MaxNum
This commit is contained in:
@@ -98,9 +98,7 @@ func (blockExec *BlockExecutor) CreateProposalBlock(
|
||||
maxBytes := state.ConsensusParams.Block.MaxBytes
|
||||
maxGas := state.ConsensusParams.Block.MaxGas
|
||||
|
||||
// Fetch a limited amount of valid evidence
|
||||
maxNumEvidence, _ := types.MaxEvidencePerBlock(maxBytes)
|
||||
evidence := blockExec.evpool.PendingEvidence(maxNumEvidence)
|
||||
evidence := blockExec.evpool.PendingEvidence(state.ConsensusParams.Evidence.MaxNum)
|
||||
|
||||
// Fetch a limited amount of valid txs
|
||||
maxDataBytes := types.MaxDataBytes(maxBytes, state.Validators.Size(), len(evidence))
|
||||
|
||||
@@ -57,11 +57,11 @@ func (_m *EvidencePool) IsPending(_a0 types.Evidence) bool {
|
||||
}
|
||||
|
||||
// PendingEvidence provides a mock function with given fields: _a0
|
||||
func (_m *EvidencePool) PendingEvidence(_a0 int64) []types.Evidence {
|
||||
func (_m *EvidencePool) PendingEvidence(_a0 uint32) []types.Evidence {
|
||||
ret := _m.Called(_a0)
|
||||
|
||||
var r0 []types.Evidence
|
||||
if rf, ok := ret.Get(0).(func(int64) []types.Evidence); ok {
|
||||
if rf, ok := ret.Get(0).(func(uint32) []types.Evidence); ok {
|
||||
r0 = rf(_a0)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
|
||||
@@ -40,17 +40,18 @@ type BlockStore interface {
|
||||
// EvidencePool defines the EvidencePool interface used by the ConsensusState.
|
||||
// Get/Set/Commit
|
||||
type EvidencePool interface {
|
||||
PendingEvidence(int64) []types.Evidence
|
||||
PendingEvidence(uint32) []types.Evidence
|
||||
AddEvidence(types.Evidence) error
|
||||
Update(*types.Block, State)
|
||||
IsCommitted(types.Evidence) bool
|
||||
IsPending(types.Evidence) bool
|
||||
}
|
||||
|
||||
// MockEvidencePool is an empty implementation of EvidencePool, useful for testing.
|
||||
type MockEvidencePool struct{}
|
||||
|
||||
func (me MockEvidencePool) PendingEvidence(int64) []types.Evidence { return nil }
|
||||
func (me MockEvidencePool) AddEvidence(types.Evidence) error { return nil }
|
||||
func (me MockEvidencePool) Update(*types.Block, State) {}
|
||||
func (me MockEvidencePool) IsCommitted(types.Evidence) bool { return false }
|
||||
func (me MockEvidencePool) IsPending(types.Evidence) bool { return false }
|
||||
func (me MockEvidencePool) PendingEvidence(uint32) []types.Evidence { return nil }
|
||||
func (me MockEvidencePool) AddEvidence(types.Evidence) error { return nil }
|
||||
func (me MockEvidencePool) Update(*types.Block, State) {}
|
||||
func (me MockEvidencePool) IsCommitted(types.Evidence) bool { return false }
|
||||
func (me MockEvidencePool) IsPending(types.Evidence) bool { return false }
|
||||
|
||||
@@ -11,6 +11,7 @@ func TxPreCheck(state State) mempl.PreCheckFunc {
|
||||
maxDataBytes := types.MaxDataBytesUnknownEvidence(
|
||||
state.ConsensusParams.Block.MaxBytes,
|
||||
state.Validators.Size(),
|
||||
state.ConsensusParams.Evidence.MaxNum,
|
||||
)
|
||||
return mempl.PreCheckAminoMaxBytes(maxDataBytes)
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
func TestTxFilter(t *testing.T) {
|
||||
genDoc := randomGenesisDoc()
|
||||
genDoc.ConsensusParams.Block.MaxBytes = 3000
|
||||
genDoc.ConsensusParams.Evidence.MaxNum = 1
|
||||
|
||||
// Max size of Txs is much smaller than size of block,
|
||||
// since we need to account for commits and evidence.
|
||||
@@ -24,10 +25,7 @@ func TestTxFilter(t *testing.T) {
|
||||
tx types.Tx
|
||||
isErr bool
|
||||
}{
|
||||
{types.Tx(tmrand.Bytes(250)), false},
|
||||
{types.Tx(tmrand.Bytes(1811)), false},
|
||||
{types.Tx(tmrand.Bytes(1831)), false},
|
||||
{types.Tx(tmrand.Bytes(1838)), true},
|
||||
{types.Tx(tmrand.Bytes(1680)), false},
|
||||
{types.Tx(tmrand.Bytes(1839)), true},
|
||||
{types.Tx(tmrand.Bytes(3000)), true},
|
||||
}
|
||||
|
||||
@@ -120,11 +120,10 @@ func validateBlock(evidencePool EvidencePool, stateDB dbm.DB, state State, block
|
||||
}
|
||||
|
||||
// Limit the amount of evidence
|
||||
maxNumEvidence, _ := types.MaxEvidencePerBlock(state.ConsensusParams.Block.MaxBytes)
|
||||
numEvidence := int64(len(block.Evidence.Evidence))
|
||||
if numEvidence > maxNumEvidence {
|
||||
return types.NewErrEvidenceOverflow(maxNumEvidence, numEvidence)
|
||||
|
||||
numEvidence := len(block.Evidence.Evidence)
|
||||
// MaxNumEvidence is capped at uint16, so conversion is always safe.
|
||||
if maxEvidence := int(state.ConsensusParams.Evidence.MaxNum); numEvidence > maxEvidence {
|
||||
return types.NewErrEvidenceOverflow(maxEvidence, numEvidence)
|
||||
}
|
||||
|
||||
// Validate all evidence.
|
||||
|
||||
@@ -216,16 +216,15 @@ func TestValidateBlockEvidence(t *testing.T) {
|
||||
for height := int64(1); height < validationTestsStopHeight; height++ {
|
||||
proposerAddr := state.Validators.GetProposer().Address
|
||||
goodEvidence := types.NewMockEvidence(height, time.Now(), proposerAddr)
|
||||
maxNumEvidence := state.ConsensusParams.Evidence.MaxNum
|
||||
if height > 1 {
|
||||
/*
|
||||
A block with too much evidence fails
|
||||
*/
|
||||
maxBlockSize := state.ConsensusParams.Block.MaxBytes
|
||||
maxNumEvidence, _ := types.MaxEvidencePerBlock(maxBlockSize)
|
||||
require.True(t, maxNumEvidence > 2)
|
||||
evidence := make([]types.Evidence, 0)
|
||||
// one more than the maximum allowed evidence
|
||||
for i := int64(0); i <= maxNumEvidence; i++ {
|
||||
for i := uint32(0); i <= maxNumEvidence; i++ {
|
||||
evidence = append(evidence, goodEvidence)
|
||||
}
|
||||
block, _ := state.MakeBlock(height, makeTxs(height), lastCommit, evidence, proposerAddr)
|
||||
@@ -237,12 +236,10 @@ func TestValidateBlockEvidence(t *testing.T) {
|
||||
/*
|
||||
A good block with several pieces of good evidence passes
|
||||
*/
|
||||
maxBlockSize := state.ConsensusParams.Block.MaxBytes
|
||||
maxNumEvidence, _ := types.MaxEvidencePerBlock(maxBlockSize)
|
||||
require.True(t, maxNumEvidence > 2)
|
||||
evidence := make([]types.Evidence, 0)
|
||||
// precisely the amount of allowed evidence
|
||||
for i := int64(0); i < maxNumEvidence; i++ {
|
||||
for i := uint32(0); i < maxNumEvidence; i++ {
|
||||
evidence = append(evidence, goodEvidence)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user