diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index b85173436..3ccf61fb1 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -29,6 +29,8 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermi - Blockchain Protocol - [types] [\#4792](https://github.com/tendermint/tendermint/pull/4792) Sort validators by voting power to enable faster commit verification (@melekes) + - [evidence] [\#4780](https://github.com/tendermint/tendermint/pull/4780) Cap evidence to an absolute number (@cmwaters) + Add `max_num` to consensus evidence parameters (default: 50 items). ### FEATURES: diff --git a/abci/types/types.pb.go b/abci/types/types.pb.go index 1d23a04a9..2572d8d8f 100644 --- a/abci/types/types.pb.go +++ b/abci/types/types.pb.go @@ -2644,6 +2644,7 @@ type EvidenceParams struct { // Note: must be greater than 0 MaxAgeNumBlocks int64 `protobuf:"varint,1,opt,name=max_age_num_blocks,json=maxAgeNumBlocks,proto3" json:"max_age_num_blocks,omitempty"` MaxAgeDuration time.Duration `protobuf:"bytes,2,opt,name=max_age_duration,json=maxAgeDuration,proto3,stdduration" json:"max_age_duration"` + MaxNumEvidence uint32 `protobuf:"varint,1,opt,name=max_num_evidence,json=maxNumEvidence,proto3" json:"max_num_evidence,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` diff --git a/abci/types/types.proto b/abci/types/types.proto index f935645ac..50c77cde0 100644 --- a/abci/types/types.proto +++ b/abci/types/types.proto @@ -302,6 +302,7 @@ message EvidenceParams { int64 max_age_num_blocks = 1; google.protobuf.Duration max_age_duration = 2 [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; + uint32 max_num = 3; } // ValidatorParams contains limits on validators. diff --git a/consensus/reactor_test.go b/consensus/reactor_test.go index 3c3eef7ed..d5f336868 100644 --- a/consensus/reactor_test.go +++ b/consensus/reactor_test.go @@ -209,7 +209,7 @@ func newMockEvidencePool(val []byte) *mockEvidencePool { } // NOTE: maxBytes is ignored -func (m *mockEvidencePool) PendingEvidence(maxBytes int64) []types.Evidence { +func (m *mockEvidencePool) PendingEvidence(maxBytes uint32) []types.Evidence { if m.height > 0 { return m.ev } diff --git a/consensus/replay_stubs.go b/consensus/replay_stubs.go index 762a0948e..542b9d6f1 100644 --- a/consensus/replay_stubs.go +++ b/consensus/replay_stubs.go @@ -50,11 +50,11 @@ type emptyEvidencePool struct{} var _ sm.EvidencePool = emptyEvidencePool{} -func (emptyEvidencePool) PendingEvidence(int64) []types.Evidence { return nil } -func (emptyEvidencePool) AddEvidence(types.Evidence) error { return nil } -func (emptyEvidencePool) Update(*types.Block, sm.State) {} -func (emptyEvidencePool) IsCommitted(types.Evidence) bool { return false } -func (emptyEvidencePool) IsPending(types.Evidence) bool { return false } +func (emptyEvidencePool) PendingEvidence(uint32) []types.Evidence { return nil } +func (emptyEvidencePool) AddEvidence(types.Evidence) error { return nil } +func (emptyEvidencePool) Update(*types.Block, sm.State) {} +func (emptyEvidencePool) IsCommitted(types.Evidence) bool { return false } +func (emptyEvidencePool) IsPending(types.Evidence) bool { return false } //----------------------------------------------------------------------------- // mockProxyApp uses ABCIResponses to give the right results. diff --git a/evidence/pool.go b/evidence/pool.go index c3708447f..f086f66b2 100644 --- a/evidence/pool.go +++ b/evidence/pool.go @@ -82,8 +82,16 @@ func NewPool(stateDB, evidenceDB dbm.DB, blockStore *store.BlockStore) (*Pool, e // PendingEvidence is used primarily as part of block proposal and returns up to maxNum of uncommitted evidence. // If maxNum is -1, all evidence is returned. Pending evidence is prioritised based on time. -func (evpool *Pool) PendingEvidence(maxNum int64) []types.Evidence { - evidence, err := evpool.listEvidence(baseKeyPending, maxNum) +func (evpool *Pool) PendingEvidence(maxNum uint32) []types.Evidence { + evidence, err := evpool.listEvidence(baseKeyPending, int64(maxNum)) + if err != nil { + evpool.logger.Error("Unable to retrieve pending evidence", "err", err) + } + return evidence +} + +func (evpool *Pool) AllPendingEvidence() []types.Evidence { + evidence, err := evpool.listEvidence(baseKeyPending, -1) if err != nil { evpool.logger.Error("Unable to retrieve pending evidence", "err", err) } @@ -300,7 +308,6 @@ func (evpool *Pool) removePendingEvidence(evidence types.Evidence) { } // listEvidence lists up to maxNum pieces of evidence for the given prefix key. -// It is wrapped by PriorityEvidence and PendingEvidence for convenience. // If maxNum is -1, there's no cap on the size of returned evidence. func (evpool *Pool) listEvidence(prefixKey byte, maxNum int64) ([]types.Evidence, error) { var count int64 diff --git a/evidence/pool_test.go b/evidence/pool_test.go index a2f26cf98..dfbd7a429 100644 --- a/evidence/pool_test.go +++ b/evidence/pool_test.go @@ -96,7 +96,7 @@ func TestProposingAndCommittingEvidence(t *testing.T) { assert.False(t, pool.IsCommitted(evidence)) // test evidence is proposed - proposedEvidence := pool.PendingEvidence(-1) + proposedEvidence := pool.AllPendingEvidence() assert.Equal(t, proposedEvidence[0], evidence) // evidence seen and committed: diff --git a/evidence/reactor_test.go b/evidence/reactor_test.go index eeedae2d1..09fc9fca7 100644 --- a/evidence/reactor_test.go +++ b/evidence/reactor_test.go @@ -92,11 +92,11 @@ func _waitForEvidence( reactors []*Reactor, ) { evpool := reactors[reactorIdx].evpool - for len(evpool.PendingEvidence(-1)) != len(evs) { + for len(evpool.AllPendingEvidence()) != len(evs) { time.Sleep(time.Millisecond * 100) } - reapedEv := evpool.PendingEvidence(-1) + reapedEv := evpool.AllPendingEvidence() // put the reaped evidence in a map so we can quickly check we got everything evMap := make(map[string]types.Evidence) for _, e := range reapedEv { diff --git a/node/node_test.go b/node/node_test.go index ef21e3094..cb8f62752 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -219,6 +219,8 @@ func testFreeAddr(t *testing.T) string { // create a proposal block using real and full // mempool and evidence pool and validate it. func TestCreateProposalBlock(t *testing.T) { + const minEvSize = 12 + config := cfg.ResetTestRoot("node_create_proposal") defer os.RemoveAll(config.RootDir) cc := proxy.NewLocalClientCreator(kvstore.NewApplication()) @@ -232,7 +234,9 @@ func TestCreateProposalBlock(t *testing.T) { var height int64 = 1 state, stateDB := state(1, height) maxBytes := 16384 + maxEvidence := 10 state.ConsensusParams.Block.MaxBytes = int64(maxBytes) + state.ConsensusParams.Evidence.MaxNum = uint32(maxEvidence) proposerAddr, _ := state.Validators.GetByIndex(0) // Make Mempool @@ -258,10 +262,8 @@ func TestCreateProposalBlock(t *testing.T) { // fill the evidence pool with more evidence // than can fit in a block - minEvSize := 12 - numEv := (maxBytes / types.MaxEvidenceBytesDenominator) / minEvSize - for i := 0; i < numEv; i++ { - ev := types.NewMockRandomEvidence(1, time.Now(), proposerAddr, tmrand.Bytes(minEvSize)) + for i := 0; i < maxEvidence+1; i++ { + ev := types.NewMockRandomEvidence(height, time.Now(), proposerAddr, tmrand.Bytes(minEvSize)) err := evidencePool.AddEvidence(ev) require.NoError(t, err) } diff --git a/proto/types/params.pb.go b/proto/types/params.pb.go index 359a8e346..ad1839122 100644 --- a/proto/types/params.pb.go +++ b/proto/types/params.pb.go @@ -146,6 +146,7 @@ type EvidenceParams struct { // Note: must be greater than 0 MaxAgeNumBlocks int64 `protobuf:"varint,1,opt,name=max_age_num_blocks,json=maxAgeNumBlocks,proto3" json:"max_age_num_blocks,omitempty"` MaxAgeDuration time.Duration `protobuf:"bytes,2,opt,name=max_age_duration,json=maxAgeDuration,proto3,stdduration" json:"max_age_duration"` + MaxNumEvidence uint32 `protobuf:"varint,1,opt,name=max_num_evidence,json=maxNumEvidence,proto3" json:"max_num_evidence,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -189,6 +190,13 @@ func (m *EvidenceParams) GetMaxAgeDuration() time.Duration { return 0 } +func (m *EvidenceParams) GetMaxNumEvidence() uint32 { + if m != nil { + return m.MaxNumEvidence + } + return 0 +} + // ValidatorParams restrict the public key types validators can use. // NOTE: uses ABCI pubkey naming, not Amino names. type ValidatorParams struct { diff --git a/proto/types/params.proto b/proto/types/params.proto index b55246f1c..4e1b1f972 100644 --- a/proto/types/params.proto +++ b/proto/types/params.proto @@ -33,6 +33,7 @@ message EvidenceParams { int64 max_age_num_blocks = 1; google.protobuf.Duration max_age_duration = 2 [(gogoproto.nullable) = false, (gogoproto.stdduration) = true]; + uint32 max_num = 3; } // ValidatorParams restrict the public key types validators can use. diff --git a/state/execution.go b/state/execution.go index cd45484ce..038379b78 100644 --- a/state/execution.go +++ b/state/execution.go @@ -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)) diff --git a/state/mocks/evidence_pool.go b/state/mocks/evidence_pool.go index 7100b2759..e3fe4a032 100644 --- a/state/mocks/evidence_pool.go +++ b/state/mocks/evidence_pool.go @@ -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 { diff --git a/state/services.go b/state/services.go index 1eb40828c..6bd06de01 100644 --- a/state/services.go +++ b/state/services.go @@ -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 } diff --git a/state/tx_filter.go b/state/tx_filter.go index a8c0627dc..0754be3b1 100644 --- a/state/tx_filter.go +++ b/state/tx_filter.go @@ -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) } diff --git a/state/tx_filter_test.go b/state/tx_filter_test.go index 2dac856bd..ed1c8a402 100644 --- a/state/tx_filter_test.go +++ b/state/tx_filter_test.go @@ -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}, } diff --git a/state/validation.go b/state/validation.go index 6d2a7eb4d..ba8c22e95 100644 --- a/state/validation.go +++ b/state/validation.go @@ -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. diff --git a/state/validation_test.go b/state/validation_test.go index 97a879156..640aa8ba3 100644 --- a/state/validation_test.go +++ b/state/validation_test.go @@ -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) } diff --git a/tools/tm-signer-harness/internal/test_harness_test.go b/tools/tm-signer-harness/internal/test_harness_test.go index aebd9e341..632bc79ea 100644 --- a/tools/tm-signer-harness/internal/test_harness_test.go +++ b/tools/tm-signer-harness/internal/test_harness_test.go @@ -47,7 +47,8 @@ const ( }, "evidence": { "max_age_num_blocks": "100000", - "max_age_duration": "172800000000000" + "max_age_duration": "172800000000000", + "max_num_evidence": 50 }, "validator": { "pub_key_types": [ diff --git a/types/block.go b/types/block.go index 7e112e5e5..5e08f4e7a 100644 --- a/types/block.go +++ b/types/block.go @@ -253,8 +253,8 @@ func MaxDataBytes(maxBytes int64, valsCount, evidenceCount int) int64 { // of evidence. // // XXX: Panics on negative result. -func MaxDataBytesUnknownEvidence(maxBytes int64, valsCount int) int64 { - _, maxEvidenceBytes := MaxEvidencePerBlock(maxBytes) +func MaxDataBytesUnknownEvidence(maxBytes int64, valsCount int, maxNumEvidence uint32) int64 { + maxEvidenceBytes := int64(maxNumEvidence) * MaxEvidenceBytes maxDataBytes := maxBytes - MaxAminoOverheadForBlock - MaxHeaderBytes - diff --git a/types/block_test.go b/types/block_test.go index 36eb0b146..00cca535e 100644 --- a/types/block_test.go +++ b/types/block_test.go @@ -399,28 +399,30 @@ func TestBlockMaxDataBytes(t *testing.T) { func TestBlockMaxDataBytesUnknownEvidence(t *testing.T) { testCases := []struct { - maxBytes int64 - valsCount int - panics bool - result int64 + maxBytes int64 + maxEvidence uint32 + valsCount int + panics bool + result int64 }{ - 0: {-10, 1, true, 0}, - 1: {10, 1, true, 0}, - 2: {961, 1, true, 0}, - 3: {962, 1, false, 0}, - 4: {963, 1, false, 1}, + 0: {-10, 0, 1, true, 0}, + 1: {10, 0, 1, true, 0}, + 2: {865, 0, 1, true, 0}, + 3: {866, 0, 1, false, 0}, + 4: {1310, 1, 1, false, 0}, + 5: {1311, 1, 1, false, 1}, } for i, tc := range testCases { tc := tc if tc.panics { assert.Panics(t, func() { - MaxDataBytesUnknownEvidence(tc.maxBytes, tc.valsCount) + MaxDataBytesUnknownEvidence(tc.maxBytes, tc.valsCount, tc.maxEvidence) }, "#%v", i) } else { assert.Equal(t, tc.result, - MaxDataBytesUnknownEvidence(tc.maxBytes, tc.valsCount), + MaxDataBytesUnknownEvidence(tc.maxBytes, tc.valsCount, tc.maxEvidence), "#%v", i) } } diff --git a/types/evidence.go b/types/evidence.go index 8fe7ab80e..84c31dd98 100644 --- a/types/evidence.go +++ b/types/evidence.go @@ -48,12 +48,12 @@ func (err *ErrEvidenceInvalid) Error() string { // ErrEvidenceOverflow is for when there is too much evidence in a block. type ErrEvidenceOverflow struct { - MaxNum int64 - GotNum int64 + MaxNum int + GotNum int } // NewErrEvidenceOverflow returns a new ErrEvidenceOverflow where got > max. -func NewErrEvidenceOverflow(max, got int64) *ErrEvidenceOverflow { +func NewErrEvidenceOverflow(max, got int) *ErrEvidenceOverflow { return &ErrEvidenceOverflow{max, got} } @@ -97,21 +97,6 @@ func RegisterMockEvidences(cdc *amino.Codec) { cdc.RegisterConcrete(MockRandomEvidence{}, "tendermint/MockRandomEvidence", nil) } -const ( - MaxEvidenceBytesDenominator = 10 -) - -// MaxEvidencePerBlock returns the maximum number of evidences -// allowed in the block and their maximum total size (limitted to 1/10th -// of the maximum block size). -// TODO: change to a constant, or to a fraction of the validator set size. -// See https://github.com/tendermint/tendermint/issues/2590 -func MaxEvidencePerBlock(blockMaxBytes int64) (int64, int64) { - maxBytes := blockMaxBytes / MaxEvidenceBytesDenominator - maxNum := maxBytes / MaxEvidenceBytes - return maxNum, maxBytes -} - //------------------------------------------- // DuplicateVoteEvidence contains evidence a validator signed two conflicting diff --git a/types/params.go b/types/params.go index d84441b84..82a16942b 100644 --- a/types/params.go +++ b/types/params.go @@ -19,6 +19,9 @@ const ( // MaxBlockPartsCount is the maximum number of block parts. MaxBlockPartsCount = (MaxBlockSizeBytes / BlockPartSizeBytes) + 1 + + // Restrict the upper bound of the amount of evidence (uses uint16 for safe conversion) + MaxEvidencePerBlock = 65535 ) // ConsensusParams contains consensus critical parameters that determine the @@ -67,6 +70,12 @@ type EvidenceParams struct { // mechanism for handling [Nothing-At-Stake // attacks](https://github.com/ethereum/wiki/wiki/Proof-of-Stake-FAQ#what-is-the-nothing-at-stake-problem-and-how-can-it-be-fixed). MaxAgeDuration time.Duration `json:"max_age_duration"` + + // This sets the maximum number of evidence that can be committed in a single block. + // and should fall comfortably under the max block bytes when we consider the size of + // each evidence (See MaxEvidenceBytes). The maximum number is MaxEvidencePerBlock. + // Default is 50 + MaxNum uint32 `json:"max_num"` } // ValidatorParams restrict the public key types validators can use. @@ -98,6 +107,7 @@ func DefaultEvidenceParams() EvidenceParams { return EvidenceParams{ MaxAgeNumBlocks: 100000, // 27.8 hrs at 1block/s MaxAgeDuration: 48 * time.Hour, + MaxNum: 50, } } @@ -148,6 +158,16 @@ func (params *ConsensusParams) Validate() error { params.Evidence.MaxAgeDuration) } + if params.Evidence.MaxNum > MaxEvidencePerBlock { + return errors.Errorf("evidenceParams.MaxNumEvidence is greater than upper bound, %d > %d", + params.Evidence.MaxNum, MaxEvidencePerBlock) + } + + if int64(params.Evidence.MaxNum)*MaxEvidenceBytes > params.Block.MaxBytes { + return errors.Errorf("total possible evidence size is bigger than block.MaxBytes, %d > %d", + int64(params.Evidence.MaxNum)*MaxEvidenceBytes, params.Block.MaxBytes) + } + if len(params.Validator.PubKeyTypes) == 0 { return errors.New("len(Validator.PubKeyTypes) must be greater than 0") } @@ -204,6 +224,7 @@ func (params ConsensusParams) Update(params2 *abci.ConsensusParams) ConsensusPar if params2.Evidence != nil { res.Evidence.MaxAgeNumBlocks = params2.Evidence.MaxAgeNumBlocks res.Evidence.MaxAgeDuration = params2.Evidence.MaxAgeDuration + res.Evidence.MaxNum = params2.Evidence.MaxNumEvidence } if params2.Validator != nil { // Copy params2.Validator.PubkeyTypes, and set result's value to the copy. diff --git a/types/params_test.go b/types/params_test.go index b446bda33..dc3a3cf0a 100644 --- a/types/params_test.go +++ b/types/params_test.go @@ -22,22 +22,24 @@ func TestConsensusParamsValidation(t *testing.T) { valid bool }{ // test block params - 0: {makeParams(1, 0, 10, 1, valEd25519), true}, - 1: {makeParams(0, 0, 10, 1, valEd25519), false}, - 2: {makeParams(47*1024*1024, 0, 10, 1, valEd25519), true}, - 3: {makeParams(10, 0, 10, 1, valEd25519), true}, - 4: {makeParams(100*1024*1024, 0, 10, 1, valEd25519), true}, - 5: {makeParams(101*1024*1024, 0, 10, 1, valEd25519), false}, - 6: {makeParams(1024*1024*1024, 0, 10, 1, valEd25519), false}, - 7: {makeParams(1024*1024*1024, 0, 10, -1, valEd25519), false}, - 8: {makeParams(1, 0, -10, 1, valEd25519), false}, + 0: {makeParams(1, 0, 10, 1, 0, valEd25519), true}, + 1: {makeParams(0, 0, 10, 1, 0, valEd25519), false}, + 2: {makeParams(47*1024*1024, 0, 10, 1, 0, valEd25519), true}, + 3: {makeParams(10, 0, 10, 1, 0, valEd25519), true}, + 4: {makeParams(100*1024*1024, 0, 10, 1, 0, valEd25519), true}, + 5: {makeParams(101*1024*1024, 0, 10, 1, 0, valEd25519), false}, + 6: {makeParams(1024*1024*1024, 0, 10, 1, 0, valEd25519), false}, + 7: {makeParams(1024*1024*1024, 0, 10, -1, 0, valEd25519), false}, + 8: {makeParams(1, 0, -10, 1, 0, valEd25519), false}, // test evidence params - 9: {makeParams(1, 0, 10, 0, valEd25519), false}, - 10: {makeParams(1, 0, 10, -1, valEd25519), false}, + 9: {makeParams(1, 0, 10, 0, 0, valEd25519), false}, + 10: {makeParams(1, 0, 10, 1, 1, valEd25519), false}, + 11: {makeParams(1000, 0, 10, 1, 1, valEd25519), true}, + 12: {makeParams(1, 0, 10, -1, 0, valEd25519), false}, // test no pubkey type provided - 11: {makeParams(1, 0, 10, 1, []string{}), false}, + 13: {makeParams(1, 0, 10, 1, 0, []string{}), false}, // test invalid pubkey type provided - 12: {makeParams(1, 0, 10, 1, []string{"potatoes make good pubkeys"}), false}, + 14: {makeParams(1, 0, 10, 1, 0, []string{"potatoes make good pubkeys"}), false}, } for i, tc := range testCases { if tc.valid { @@ -52,6 +54,7 @@ func makeParams( blockBytes, blockGas int64, blockTimeIotaMs int64, evidenceAge int64, + maxEvidence uint32, pubkeyTypes []string, ) ConsensusParams { return ConsensusParams{ @@ -63,6 +66,7 @@ func makeParams( Evidence: EvidenceParams{ MaxAgeNumBlocks: evidenceAge, MaxAgeDuration: time.Duration(evidenceAge), + MaxNum: maxEvidence, }, Validator: ValidatorParams{ PubKeyTypes: pubkeyTypes, @@ -72,14 +76,14 @@ func makeParams( func TestConsensusParamsHash(t *testing.T) { params := []ConsensusParams{ - makeParams(4, 2, 10, 3, valEd25519), - makeParams(1, 4, 10, 3, valEd25519), - makeParams(1, 2, 10, 4, valEd25519), - makeParams(2, 5, 10, 7, valEd25519), - makeParams(1, 7, 10, 6, valEd25519), - makeParams(9, 5, 10, 4, valEd25519), - makeParams(7, 8, 10, 9, valEd25519), - makeParams(4, 6, 10, 5, valEd25519), + makeParams(4, 2, 10, 3, 1, valEd25519), + makeParams(1, 4, 10, 3, 1, valEd25519), + makeParams(1, 2, 10, 4, 1, valEd25519), + makeParams(2, 5, 10, 7, 1, valEd25519), + makeParams(1, 7, 10, 6, 1, valEd25519), + makeParams(9, 5, 10, 4, 1, valEd25519), + makeParams(7, 8, 10, 9, 1, valEd25519), + makeParams(4, 6, 10, 5, 1, valEd25519), } hashes := make([][]byte, len(params)) @@ -105,13 +109,13 @@ func TestConsensusParamsUpdate(t *testing.T) { }{ // empty updates { - makeParams(1, 2, 10, 3, valEd25519), + makeParams(1, 2, 10, 3, 0, valEd25519), &abci.ConsensusParams{}, - makeParams(1, 2, 10, 3, valEd25519), + makeParams(1, 2, 10, 3, 0, valEd25519), }, // fine updates { - makeParams(1, 2, 10, 3, valEd25519), + makeParams(1, 2, 10, 3, 0, valEd25519), &abci.ConsensusParams{ Block: &abci.BlockParams{ MaxBytes: 100, @@ -120,12 +124,13 @@ func TestConsensusParamsUpdate(t *testing.T) { Evidence: &abci.EvidenceParams{ MaxAgeNumBlocks: 300, MaxAgeDuration: time.Duration(300), + MaxNumEvidence: 50, }, Validator: &abci.ValidatorParams{ PubKeyTypes: valSecp256k1, }, }, - makeParams(100, 200, 10, 300, valSecp256k1), + makeParams(100, 200, 10, 300, 50, valSecp256k1), }, } for _, tc := range testCases { diff --git a/types/protobuf.go b/types/protobuf.go index a185722f1..bc15d914d 100644 --- a/types/protobuf.go +++ b/types/protobuf.go @@ -139,6 +139,7 @@ func (tm2pb) ConsensusParams(params *ConsensusParams) *abci.ConsensusParams { Evidence: &abci.EvidenceParams{ MaxAgeNumBlocks: params.Evidence.MaxAgeNumBlocks, MaxAgeDuration: params.Evidence.MaxAgeDuration, + MaxNumEvidence: params.Evidence.MaxNum, }, Validator: &abci.ValidatorParams{ PubKeyTypes: params.Validator.PubKeyTypes,