From 08aa4765b07641a7d1e9f84e9b1be7b6172dbd78 Mon Sep 17 00:00:00 2001 From: Callum Date: Tue, 28 Apr 2020 12:54:13 +0200 Subject: [PATCH] create tests for validating evidence --- state/validation.go | 2 +- state/validation_test.go | 66 +++++++++++++++++++++++++++++++++++++--- types/evidence.go | 8 ++++- 3 files changed, 69 insertions(+), 7 deletions(-) diff --git a/state/validation.go b/state/validation.go index aecfd42c8..c3231c270 100644 --- a/state/validation.go +++ b/state/validation.go @@ -137,7 +137,7 @@ func validateBlock(evidencePool EvidencePool, stateDB dbm.DB, state State, block return types.NewErrEvidenceInvalid(ev, errors.New("evidence was already committed")) } if evidencePool.IsPending(ev) { - return nil + continue } } if err := VerifyEvidence(stateDB, state, ev, &block.Header); err != nil { diff --git a/state/validation_test.go b/state/validation_test.go index 10ff4c8ea..1be09c8dc 100644 --- a/state/validation_test.go +++ b/state/validation_test.go @@ -8,6 +8,7 @@ import ( "github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/crypto/tmhash" + evmock "github.com/tendermint/tendermint/evidence/mock" "github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/mock" sm "github.com/tendermint/tendermint/state" @@ -98,7 +99,7 @@ func TestValidateBlockCommit(t *testing.T) { log.TestingLogger(), proxyApp.Consensus(), mock.Mempool{}, - sm.MockEvidencePool{}, + evmock.NewDefaultEvidencePool(), ) lastCommit := types.NewCommit(0, 0, types.BlockID{}, nil) wrongSigsCommit := types.NewCommit(1, 0, types.BlockID{}, nil) @@ -205,7 +206,7 @@ func TestValidateBlockEvidence(t *testing.T) { log.TestingLogger(), proxyApp.Consensus(), mock.Mempool{}, - sm.MockEvidencePool{}, + evmock.NewDefaultEvidencePool(), ) lastCommit := types.NewCommit(0, 0, types.BlockID{}, nil) @@ -260,15 +261,70 @@ func TestValidateFailBlockOnCommittedEvidence(t *testing.T) { var height int64 = 1 state, stateDB, _ := makeState(1, int(height)) - blockExec := sm.NewBlockExecutor(stateDB, log.TestingLogger(), nil, nil, mockEvPoolAlwaysCommitted{}) + evpool := evmock.NewDefaultEvidencePool() + blockExec := sm.NewBlockExecutor( + stateDB, log.TestingLogger(), + nil, + nil, + evpool) // A block with a couple pieces of evidence passes. block := makeBlock(state, height) addr, _ := state.Validators.GetByIndex(0) - alreadyCommittedEvidence := types.NewMockEvidence(height, time.Now(), addr) - block.Evidence.Evidence = []types.Evidence{alreadyCommittedEvidence} + evpool.CommitEvidence(evpool.AddMockEvidence(height, addr)) + block.Evidence.Evidence = evpool.CommittedEvidenceList block.EvidenceHash = block.Evidence.Hash() err := blockExec.ValidateBlock(state, block) require.Error(t, err) require.IsType(t, err, &types.ErrEvidenceInvalid{}) } + +func TestValidateAlreadyPendingEvidence(t *testing.T) { + var height int64 = 1 + state, stateDB, _ := makeState(2, int(height)) + + evpool := evmock.NewDefaultEvidencePool() + blockExec := sm.NewBlockExecutor( + stateDB, log.TestingLogger(), + nil, + nil, + evpool) + // A block with a couple pieces of evidence passes. + block := makeBlock(state, height) + addr, _ := state.Validators.GetByIndex(0) + addr2, _ := state.Validators.GetByIndex(0) + // add pending evidence + pendingEv := evpool.AddMockEvidence(height, addr) + // add evidence that hasn't seen before + ev := types.NewMockEvidence(height, time.Now(), addr2) + block.Evidence.Evidence = []types.Evidence{pendingEv, ev} + block.EvidenceHash = block.Evidence.Hash() + err := blockExec.ValidateBlock(state, block) + + require.NoError(t, err) +} + +// TODO: prevent committing duplicate votes +//func TestValidateDuplicateEvidenceShouldFail(t *testing.T) { +// var height int64 = 1 +// var evidence []types.Evidence +// state, stateDB, _ := makeState(1, int(height)) +// +// evpool := evmock.NewDefaultEvidencePool() +// blockExec := sm.NewBlockExecutor( +// stateDB, log.TestingLogger(), +// nil, +// nil, +// evpool) +// // A block with a couple pieces of evidence passes. +// block := makeBlock(state, height) +// addr, _ := state.Validators.GetByIndex(0) +// for i := 0; i < 2; i++ { +// evidence = append(evidence, types.NewMockEvidence(height, time.Now(), addr)) +// } +// block.Evidence.Evidence = evidence +// block.EvidenceHash = block.Evidence.Hash() +// err := blockExec.ValidateBlock(state, block) +// +// require.Error(t, err) +//} diff --git a/types/evidence.go b/types/evidence.go index 9dd7c9823..fef9977c0 100644 --- a/types/evidence.go +++ b/types/evidence.go @@ -975,7 +975,13 @@ func (e MockEvidence) Bytes() []byte { return []byte(fmt.Sprintf("%d-%x-%s", e.EvidenceHeight, e.EvidenceAddress, e.EvidenceTime)) } -func (e MockEvidence) Verify(chainID string, pubKey crypto.PubKey) error { return nil } +func (e MockEvidence) Verify(chainID string, pubKey crypto.PubKey) error { + if !bytes.Equal(pubKey.Address(), e.Address()) { + return fmt.Errorf("address (%X) doesn't match pubkey (%v - %X)", + e.Address(), pubKey, pubKey.Address()) + } + return nil +} func (e MockEvidence) Equal(ev Evidence) bool { e2 := ev.(MockEvidence) return e.EvidenceHeight == e2.EvidenceHeight &&