Browse Source

evidence: replace mock evidence with mocked duplicate vote evidence (#5036)

pull/5046/head v0.34.0-dev1
Callum Waters 4 years ago
committed by GitHub
parent
commit
3ecc0ffe7e
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 222 additions and 1057 deletions
  1. +3
    -5
      consensus/reactor_test.go
  2. +39
    -29
      evidence/pool_test.go
  3. +9
    -11
      evidence/reactor_test.go
  4. +9
    -10
      node/node_test.go
  5. +78
    -832
      proto/tendermint/types/evidence.pb.go
  6. +0
    -19
      proto/tendermint/types/evidence.proto
  7. +3
    -3
      state/execution_test.go
  8. +33
    -26
      state/validation_test.go
  9. +8
    -8
      types/block_test.go
  10. +38
    -104
      types/evidence.go
  11. +2
    -7
      types/evidence_test.go
  12. +0
    -3
      types/protobuf.go

+ 3
- 5
consensus/reactor_test.go View File

@ -154,9 +154,7 @@ func TestReactorWithEvidence(t *testing.T) {
// mock the evidence pool
// everyone includes evidence of another double signing
vIdx := (i + 1) % nValidators
pubKey, err := privVals[vIdx].GetPubKey()
require.NoError(t, err)
evpool := newMockEvidencePool(pubKey.Address())
evpool := newMockEvidencePool(privVals[vIdx])
// Make State
blockExec := sm.NewBlockExecutor(stateDB, log.TestingLogger(), proxyAppConnCon, mempool, evpool)
@ -201,9 +199,9 @@ type mockEvidencePool struct {
ev []types.Evidence
}
func newMockEvidencePool(val []byte) *mockEvidencePool {
func newMockEvidencePool(val types.PrivValidator) *mockEvidencePool {
return &mockEvidencePool{
ev: []types.Evidence{types.NewMockEvidence(1, time.Now().UTC(), val)},
ev: []types.Evidence{types.NewMockDuplicateVoteEvidenceWithValidator(1, time.Now().UTC(), val, config.ChainID())},
}
}


+ 39
- 29
evidence/pool_test.go View File

@ -11,7 +11,6 @@ import (
dbm "github.com/tendermint/tm-db"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/tmhash"
"github.com/tendermint/tendermint/libs/bytes"
"github.com/tendermint/tendermint/libs/log"
@ -33,16 +32,17 @@ const evidenceChainID = "test_chain"
func TestEvidencePool(t *testing.T) {
var (
valAddr = tmrand.Bytes(crypto.AddressSize)
val = types.NewMockPV()
valAddr = val.PrivKey.PubKey().Address()
height = int64(52)
stateDB = initializeValidatorState(valAddr, height)
stateDB = initializeValidatorState(val, height)
evidenceDB = dbm.NewMemDB()
blockStoreDB = dbm.NewMemDB()
blockStore = initializeBlockStore(blockStoreDB, sm.LoadState(stateDB), valAddr)
evidenceTime = time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC)
goodEvidence = types.NewMockEvidence(height, time.Now(), valAddr)
badEvidence = types.NewMockEvidence(1, evidenceTime, valAddr)
goodEvidence = types.NewMockDuplicateVoteEvidenceWithValidator(height, evidenceTime, val, evidenceChainID)
badEvidence = types.NewMockDuplicateVoteEvidenceWithValidator(1, evidenceTime, val, evidenceChainID)
)
pool, err := NewPool(stateDB, evidenceDB, blockStore)
@ -82,12 +82,12 @@ func TestEvidencePool(t *testing.T) {
func TestProposingAndCommittingEvidence(t *testing.T) {
var (
valAddr = tmrand.Bytes(crypto.AddressSize)
val = types.NewMockPV()
height = int64(1)
stateDB = initializeValidatorState(valAddr, height)
stateDB = initializeValidatorState(val, height)
evidenceDB = dbm.NewMemDB()
blockStoreDB = dbm.NewMemDB()
blockStore = initializeBlockStore(blockStoreDB, sm.LoadState(stateDB), valAddr)
blockStore = initializeBlockStore(blockStoreDB, sm.LoadState(stateDB), val.PrivKey.PubKey().Address())
evidenceTime = time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC)
)
@ -95,7 +95,7 @@ func TestProposingAndCommittingEvidence(t *testing.T) {
require.NoError(t, err)
// evidence not seen yet:
evidence := types.NewMockEvidence(height, evidenceTime, valAddr)
evidence := types.NewMockDuplicateVoteEvidenceWithValidator(height, evidenceTime, val, evidenceChainID)
assert.False(t, pool.IsCommitted(evidence))
// evidence seen but not yet committed:
@ -117,9 +117,10 @@ func TestProposingAndCommittingEvidence(t *testing.T) {
func TestAddEvidence(t *testing.T) {
var (
valAddr = tmrand.Bytes(crypto.AddressSize)
val = types.NewMockPV()
valAddr = val.PrivKey.PubKey().Address()
height = int64(30)
stateDB = initializeValidatorState(valAddr, height)
stateDB = initializeValidatorState(val, height)
evidenceDB = dbm.NewMemDB()
blockStoreDB = dbm.NewMemDB()
blockStore = initializeBlockStore(blockStoreDB, sm.LoadState(stateDB), valAddr)
@ -145,7 +146,7 @@ func TestAddEvidence(t *testing.T) {
for _, tc := range testCases {
tc := tc
t.Run(tc.evDescription, func(t *testing.T) {
ev := types.NewMockEvidence(tc.evHeight, tc.evTime, valAddr)
ev := types.NewMockDuplicateVoteEvidence(tc.evHeight, tc.evTime, evidenceChainID)
err := pool.AddEvidence(ev)
if tc.expErr {
assert.Error(t, err)
@ -157,9 +158,10 @@ func TestAddEvidence(t *testing.T) {
func TestEvidencePoolUpdate(t *testing.T) {
var (
valAddr = tmrand.Bytes(crypto.AddressSize)
val = types.NewMockPV()
valAddr = val.PrivKey.PubKey().Address()
height = int64(21)
stateDB = initializeValidatorState(valAddr, height)
stateDB = initializeValidatorState(val, height)
evidenceDB = dbm.NewMemDB()
blockStoreDB = dbm.NewMemDB()
state = sm.LoadState(stateDB)
@ -170,7 +172,7 @@ func TestEvidencePoolUpdate(t *testing.T) {
require.NoError(t, err)
// create new block (no need to save it to blockStore)
evidence := types.NewMockEvidence(height, time.Now(), valAddr)
evidence := types.NewMockDuplicateVoteEvidence(height, time.Now(), evidenceChainID)
lastCommit := makeCommit(height, valAddr)
block := types.MakeBlock(height+1, []types.Tx{}, lastCommit, []types.Evidence{evidence})
// update state (partially)
@ -186,9 +188,10 @@ func TestEvidencePoolUpdate(t *testing.T) {
func TestEvidencePoolNewPool(t *testing.T) {
var (
valAddr = tmrand.Bytes(crypto.AddressSize)
val = types.NewMockPV()
valAddr = val.PrivKey.PubKey().Address()
height = int64(1)
stateDB = initializeValidatorState(valAddr, height)
stateDB = initializeValidatorState(val, height)
evidenceDB = dbm.NewMemDB()
blockStoreDB = dbm.NewMemDB()
state = sm.LoadState(stateDB)
@ -204,8 +207,9 @@ func TestEvidencePoolNewPool(t *testing.T) {
func TestAddingAndPruningPOLC(t *testing.T) {
var (
valAddr = tmrand.Bytes(crypto.AddressSize)
stateDB = initializeValidatorState(valAddr, 1)
val = types.NewMockPV()
valAddr = val.PrivKey.PubKey().Address()
stateDB = initializeValidatorState(val, 1)
evidenceDB = dbm.NewMemDB()
blockStoreDB = dbm.NewMemDB()
state = sm.LoadState(stateDB)
@ -221,7 +225,6 @@ func TestAddingAndPruningPOLC(t *testing.T) {
}
)
val := types.NewMockPV()
voteA := makeVote(1, 1, 0, val.PrivKey.PubKey().Address(), firstBlockID, evidenceTime)
vA := voteA.ToProto()
err := val.SignVote(evidenceChainID, vA)
@ -267,16 +270,17 @@ func TestAddingAndPruningPOLC(t *testing.T) {
func TestRecoverPendingEvidence(t *testing.T) {
var (
valAddr = tmrand.Bytes(crypto.AddressSize)
val = types.NewMockPV()
valAddr = val.PrivKey.PubKey().Address()
height = int64(30)
stateDB = initializeValidatorState(valAddr, height)
stateDB = initializeValidatorState(val, height)
evidenceDB = dbm.NewMemDB()
blockStoreDB = dbm.NewMemDB()
state = sm.LoadState(stateDB)
blockStore = initializeBlockStore(blockStoreDB, state, valAddr)
evidenceTime = time.Date(2019, 1, 1, 0, 0, 0, 0, time.UTC)
goodEvidence = types.NewMockEvidence(height, time.Now(), valAddr)
expiredEvidence = types.NewMockEvidence(int64(1), evidenceTime, valAddr)
goodEvidence = types.NewMockDuplicateVoteEvidenceWithValidator(height, time.Now(), val, evidenceChainID)
expiredEvidence = types.NewMockDuplicateVoteEvidenceWithValidator(int64(1), evidenceTime, val, evidenceChainID)
)
// load good evidence
@ -461,8 +465,14 @@ func TestAddingPotentialAmnesiaEvidence(t *testing.T) {
pool.logger.Info("CASE F")
// a new amnesia evidence is seen. It has an empty polc so we should extract the potential amnesia evidence
// and start our own trial
newPe := types.NewPotentialAmnesiaEvidence(voteB, voteD)
newAe := types.NewAmnesiaEvidence(newPe, types.NewEmptyPOLC())
newPe := &types.PotentialAmnesiaEvidence{
VoteA: voteB,
VoteB: voteD,
}
newAe := &types.AmnesiaEvidence{
PotentialAmnesiaEvidence: newPe,
Polc: types.NewEmptyPOLC(),
}
err = pool.AddEvidence(newAe)
assert.NoError(t, err)
assert.Equal(t, 2, len(pool.AllPendingEvidence()))
@ -518,10 +528,10 @@ func initializeStateFromValidatorSet(valSet *types.ValidatorSet, height int64) d
return stateDB
}
func initializeValidatorState(valAddr []byte, height int64) dbm.DB {
func initializeValidatorState(privVal types.PrivValidator, height int64) dbm.DB {
pubKey, _ := types.NewMockPV().GetPubKey()
validator := &types.Validator{Address: valAddr, VotingPower: 0, PubKey: pubKey}
pubKey, _ := privVal.GetPubKey()
validator := &types.Validator{Address: pubKey.Address(), VotingPower: 0, PubKey: pubKey}
// create validator set and state
valSet := &types.ValidatorSet{


+ 9
- 11
evidence/reactor_test.go View File

@ -13,9 +13,7 @@ import (
dbm "github.com/tendermint/tm-db"
cfg "github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/libs/log"
tmrand "github.com/tendermint/tendermint/libs/rand"
"github.com/tendermint/tendermint/p2p"
sm "github.com/tendermint/tendermint/state"
"github.com/tendermint/tendermint/types"
@ -114,10 +112,10 @@ func _waitForEvidence(
wg.Done()
}
func sendEvidence(t *testing.T, evpool *Pool, valAddr []byte, n int) types.EvidenceList {
func sendEvidence(t *testing.T, evpool *Pool, val types.PrivValidator, n int) types.EvidenceList {
evList := make([]types.Evidence, n)
for i := 0; i < n; i++ {
ev := types.NewMockEvidence(int64(i+1), time.Now().UTC(), valAddr)
ev := types.NewMockDuplicateVoteEvidenceWithValidator(int64(i+1), time.Now().UTC(), val, evidenceChainID)
err := evpool.AddEvidence(ev)
require.NoError(t, err)
evList[i] = ev
@ -136,11 +134,11 @@ func TestReactorBroadcastEvidence(t *testing.T) {
// create statedb for everyone
stateDBs := make([]dbm.DB, N)
valAddr := tmrand.Bytes(crypto.AddressSize)
val := types.NewMockPV()
// we need validators saved for heights at least as high as we have evidence for
height := int64(numEvidence) + 10
for i := 0; i < N; i++ {
stateDBs[i] = initializeValidatorState(valAddr, height)
stateDBs[i] = initializeValidatorState(val, height)
}
// make reactors from statedb
@ -156,7 +154,7 @@ func TestReactorBroadcastEvidence(t *testing.T) {
// send a bunch of valid evidence to the first reactor's evpool
// and wait for them all to be received in the others
evList := sendEvidence(t, reactors[0].evpool, valAddr, numEvidence)
evList := sendEvidence(t, reactors[0].evpool, val, numEvidence)
waitForEvidence(t, evList, reactors)
}
@ -171,13 +169,13 @@ func (ps peerState) GetHeight() int64 {
func TestReactorSelectiveBroadcast(t *testing.T) {
config := cfg.TestConfig()
valAddr := tmrand.Bytes(crypto.AddressSize)
val := types.NewMockPV()
height1 := int64(numEvidence) + 10
height2 := int64(numEvidence) / 2
// DB1 is ahead of DB2
stateDB1 := initializeValidatorState(valAddr, height1)
stateDB2 := initializeValidatorState(valAddr, height2)
stateDB1 := initializeValidatorState(val, height1)
stateDB2 := initializeValidatorState(val, height2)
// make reactors from statedb
reactors := makeAndConnectReactors(config, []dbm.DB{stateDB1, stateDB2})
@ -196,7 +194,7 @@ func TestReactorSelectiveBroadcast(t *testing.T) {
peer.Set(types.PeerStateKey, ps)
// send a bunch of valid evidence to the first reactor's evpool
evList := sendEvidence(t, reactors[0].evpool, valAddr, numEvidence)
evList := sendEvidence(t, reactors[0].evpool, val, numEvidence)
// only ones less than the peers height should make it through
waitForEvidence(t, evList[:numEvidence/2], reactors[1:2])


+ 9
- 10
node/node_test.go View File

@ -218,8 +218,6 @@ 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())
@ -231,7 +229,7 @@ func TestCreateProposalBlock(t *testing.T) {
logger := log.TestingLogger()
var height int64 = 1
state, stateDB := state(1, height)
state, stateDB, privVals := state(1, height)
maxBytes := 16384
maxEvidence := 10
state.ConsensusParams.Block.MaxBytes = int64(maxBytes)
@ -260,7 +258,7 @@ func TestCreateProposalBlock(t *testing.T) {
// fill the evidence pool with more evidence
// than can fit in a block
for i := 0; i <= maxEvidence; i++ {
ev := types.NewMockRandomEvidence(height, time.Now(), proposerAddr, tmrand.Bytes(minEvSize))
ev := types.NewMockDuplicateVoteEvidenceWithValidator(height, time.Now(), privVals[0], "test-chain")
err := evidencePool.AddEvidence(ev)
require.NoError(t, err)
}
@ -326,14 +324,15 @@ func TestNodeNewNodeCustomReactors(t *testing.T) {
assert.Equal(t, customBlockchainReactor, n.Switch().Reactor("BLOCKCHAIN"))
}
func state(nVals int, height int64) (sm.State, dbm.DB) {
func state(nVals int, height int64) (sm.State, dbm.DB, []types.PrivValidator) {
privVals := make([]types.PrivValidator, nVals)
vals := make([]types.GenesisValidator, nVals)
for i := 0; i < nVals; i++ {
secret := []byte(fmt.Sprintf("test%d", i))
pk := ed25519.GenPrivKeyFromSecret(secret)
privVal := types.NewMockPV()
privVals[i] = privVal
vals[i] = types.GenesisValidator{
Address: pk.PubKey().Address(),
PubKey: pk.PubKey(),
Address: privVal.PrivKey.PubKey().Address(),
PubKey: privVal.PrivKey.PubKey(),
Power: 1000,
Name: fmt.Sprintf("test%d", i),
}
@ -353,5 +352,5 @@ func state(nVals int, height int64) (sm.State, dbm.DB) {
s.LastValidators = s.Validators.Copy()
sm.SaveState(stateDB, s)
}
return s, stateDB
return s, stateDB, privVals
}

+ 78
- 832
proto/tendermint/types/evidence.pb.go
File diff suppressed because it is too large
View File


+ 0
- 19
proto/tendermint/types/evidence.proto View File

@ -4,7 +4,6 @@ package tendermint.types;
option go_package = "github.com/tendermint/tendermint/proto/tendermint/types";
import "gogoproto/gogo.proto";
import "google/protobuf/timestamp.proto";
import "tendermint/types/types.proto";
import "tendermint/crypto/keys/types.proto";
@ -27,21 +26,6 @@ message AmnesiaEvidence {
ProofOfLockChange polc = 2;
}
// MockEvidence is used for testing pruposes
message MockEvidence {
int64 evidence_height = 1;
google.protobuf.Timestamp evidence_time = 2
[(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
bytes evidence_address = 3;
}
message MockRandomEvidence {
int64 evidence_height = 1;
google.protobuf.Timestamp evidence_time = 2
[(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
bytes evidence_address = 3;
bytes rand_bytes = 4;
}
message ConflictingHeadersEvidence {
SignedHeader h1 = 1;
SignedHeader h2 = 2;
@ -66,9 +50,6 @@ message Evidence {
PotentialAmnesiaEvidence potential_amnesia_evidence = 4;
AmnesiaEvidence amnesia_evidence = 5;
PhantomValidatorEvidence phantom_validator_evidence = 6;
MockEvidence mock_evidence = 7;
MockRandomEvidence mock_random_evidence = 8;
}
}


+ 3
- 3
state/execution_test.go View File

@ -121,7 +121,7 @@ func TestBeginBlockByzantineValidators(t *testing.T) {
require.Nil(t, err)
defer proxyApp.Stop()
state, stateDB, _ := makeState(2, 12)
state, stateDB, privVals := makeState(2, 12)
prevHash := state.LastBlockID.Hash
prevParts := types.PartSetHeader{}
@ -129,8 +129,8 @@ func TestBeginBlockByzantineValidators(t *testing.T) {
height1, val1 := int64(8), state.Validators.Validators[0].Address
height2, val2 := int64(3), state.Validators.Validators[1].Address
ev1 := types.NewMockEvidence(height1, time.Now(), val1)
ev2 := types.NewMockEvidence(height2, time.Now(), val2)
ev1 := types.NewMockDuplicateVoteEvidenceWithValidator(height1, time.Now(), privVals[val1.String()], chainID)
ev2 := types.NewMockDuplicateVoteEvidenceWithValidator(height2, time.Now(), privVals[val2.String()], chainID)
now := tmtime.Now()
valSet := state.Validators


+ 33
- 26
state/validation_test.go View File

@ -5,7 +5,6 @@ import (
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/libs/bytes"
@ -238,7 +237,8 @@ func TestValidateBlockEvidence(t *testing.T) {
evidence := make([]types.Evidence, 0)
// one more than the maximum allowed evidence
for i := uint32(0); i <= maxNumEvidence; i++ {
evidence = append(evidence, types.NewMockEvidence(height, time.Now(), proposerAddr))
evidence = append(evidence, types.NewMockDuplicateVoteEvidenceWithValidator(height, time.Now(),
privVals[proposerAddr.String()], chainID))
}
block, _ := state.MakeBlock(height, makeTxs(height), lastCommit, evidence, proposerAddr)
err := blockExec.ValidateBlock(state, block)
@ -254,8 +254,9 @@ func TestValidateBlockEvidence(t *testing.T) {
// precisely the amount of allowed evidence
for i := int32(0); uint32(i) < maxNumEvidence; i++ {
// make different evidence for each validator
addr, _ := state.Validators.GetByIndex(i)
evidence = append(evidence, types.NewMockEvidence(height, time.Now(), addr))
_, val := state.Validators.GetByIndex(i)
evidence = append(evidence, types.NewMockDuplicateVoteEvidenceWithValidator(height, time.Now(),
privVals[val.Address.String()], chainID))
}
var err error
@ -274,14 +275,17 @@ func TestValidateBlockEvidence(t *testing.T) {
func TestValidateFailBlockOnCommittedEvidence(t *testing.T) {
var height int64 = 1
state, stateDB, _ := makeState(2, int(height))
addr, _ := state.Validators.GetByIndex(0)
addr2, _ := state.Validators.GetByIndex(1)
ev := types.NewMockEvidence(height, defaultTestTime, addr)
ev2 := types.NewMockEvidence(height, defaultTestTime, addr2)
state, stateDB, privVals := makeState(2, int(height))
_, val := state.Validators.GetByIndex(0)
_, val2 := state.Validators.GetByIndex(1)
ev := types.NewMockDuplicateVoteEvidenceWithValidator(height, defaultTestTime,
privVals[val.Address.String()], chainID)
ev2 := types.NewMockDuplicateVoteEvidenceWithValidator(height, defaultTestTime,
privVals[val2.Address.String()], chainID)
evpool := &mocks.EvidencePool{}
evpool.On("IsPending", mock.AnythingOfType("types.MockEvidence")).Return(false)
evpool.On("IsPending", ev).Return(false)
evpool.On("IsPending", ev2).Return(false)
evpool.On("IsCommitted", ev).Return(false)
evpool.On("IsCommitted", ev2).Return(true)
@ -302,16 +306,19 @@ func TestValidateFailBlockOnCommittedEvidence(t *testing.T) {
func TestValidateAlreadyPendingEvidence(t *testing.T) {
var height int64 = 1
state, stateDB, _ := makeState(2, int(height))
addr, _ := state.Validators.GetByIndex(0)
addr2, _ := state.Validators.GetByIndex(1)
ev := types.NewMockEvidence(height, defaultTestTime, addr)
ev2 := types.NewMockEvidence(height, defaultTestTime, addr2)
state, stateDB, privVals := makeState(2, int(height))
_, val := state.Validators.GetByIndex(0)
_, val2 := state.Validators.GetByIndex(1)
ev := types.NewMockDuplicateVoteEvidenceWithValidator(height, defaultTestTime,
privVals[val.Address.String()], chainID)
ev2 := types.NewMockDuplicateVoteEvidenceWithValidator(height, defaultTestTime,
privVals[val2.Address.String()], chainID)
evpool := &mocks.EvidencePool{}
evpool.On("IsPending", ev).Return(false)
evpool.On("IsPending", ev2).Return(true)
evpool.On("IsCommitted", mock.AnythingOfType("types.MockEvidence")).Return(false)
evpool.On("IsCommitted", ev).Return(false)
evpool.On("IsCommitted", ev2).Return(false)
blockExec := sm.NewBlockExecutor(
stateDB, log.TestingLogger(),
@ -330,11 +337,13 @@ func TestValidateAlreadyPendingEvidence(t *testing.T) {
func TestValidateDuplicateEvidenceShouldFail(t *testing.T) {
var height int64 = 1
state, stateDB, _ := makeState(1, int(height))
addr, _ := state.Validators.GetByIndex(0)
addr2, _ := state.Validators.GetByIndex(1)
ev := types.NewMockEvidence(height, defaultTestTime, addr)
ev2 := types.NewMockEvidence(height, defaultTestTime, addr2)
state, stateDB, privVals := makeState(2, int(height))
_, val := state.Validators.GetByIndex(0)
_, val2 := state.Validators.GetByIndex(1)
ev := types.NewMockDuplicateVoteEvidenceWithValidator(height, defaultTestTime,
privVals[val.Address.String()], chainID)
ev2 := types.NewMockDuplicateVoteEvidenceWithValidator(height, defaultTestTime,
privVals[val2.Address.String()], chainID)
blockExec := sm.NewBlockExecutor(
stateDB, log.TestingLogger(),
@ -454,8 +463,7 @@ func TestValidatePrimedAmnesiaEvidence(t *testing.T) {
func TestVerifyEvidenceWrongAddress(t *testing.T) {
var height int64 = 1
state, stateDB, _ := makeState(1, int(height))
randomAddr := []byte("wrong address")
ev := types.NewMockEvidence(height, defaultTestTime, randomAddr)
ev := types.NewMockDuplicateVoteEvidence(height, defaultTestTime, chainID)
blockExec := sm.NewBlockExecutor(
stateDB, log.TestingLogger(),
@ -467,7 +475,7 @@ func TestVerifyEvidenceWrongAddress(t *testing.T) {
block.Evidence.Evidence = []types.Evidence{ev}
block.EvidenceHash = block.Evidence.Hash()
err := blockExec.ValidateBlock(state, block)
errMsg := "Invalid evidence: address 77726F6E672061646472657373 was not a validator at height 1"
errMsg := "Invalid evidence: address "
if assert.Error(t, err) {
assert.Equal(t, err.Error()[:len(errMsg)], errMsg)
}
@ -477,8 +485,7 @@ func TestVerifyEvidenceExpiredEvidence(t *testing.T) {
var height int64 = 4
state, stateDB, _ := makeState(1, int(height))
state.ConsensusParams.Evidence.MaxAgeNumBlocks = 1
addr, _ := state.Validators.GetByIndex(0)
ev := types.NewMockEvidence(1, defaultTestTime, addr)
ev := types.NewMockDuplicateVoteEvidence(1, defaultTestTime, chainID)
err := sm.VerifyEvidence(stateDB, state, ev, nil)
errMsg := "evidence from height 1 (created at: 2019-01-01 00:00:00 +0000 UTC) is too old"
if assert.Error(t, err) {


+ 8
- 8
types/block_test.go View File

@ -36,11 +36,11 @@ func TestBlockAddEvidence(t *testing.T) {
lastID := makeBlockIDRandom()
h := int64(3)
voteSet, valSet, vals := randVoteSet(h-1, 1, tmproto.PrecommitType, 10, 1)
voteSet, _, vals := randVoteSet(h-1, 1, tmproto.PrecommitType, 10, 1)
commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals, time.Now())
require.NoError(t, err)
ev := NewMockEvidence(h, time.Now(), valSet.Validators[0].Address)
ev := NewMockDuplicateVoteEvidenceWithValidator(h, time.Now(), vals[0], "block-test-chain")
evList := []Evidence{ev}
block := MakeBlock(h, txs, commit, evList)
@ -60,7 +60,7 @@ func TestBlockValidateBasic(t *testing.T) {
commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals, time.Now())
require.NoError(t, err)
ev := NewMockEvidence(h, time.Now(), valSet.Validators[0].Address)
ev := NewMockDuplicateVoteEvidenceWithValidator(h, time.Now(), vals[0], "block-test-chain")
evList := []Evidence{ev}
testCases := []struct {
@ -125,16 +125,16 @@ func TestBlockMakePartSetWithEvidence(t *testing.T) {
lastID := makeBlockIDRandom()
h := int64(3)
voteSet, valSet, vals := randVoteSet(h-1, 1, tmproto.PrecommitType, 10, 1)
voteSet, _, vals := randVoteSet(h-1, 1, tmproto.PrecommitType, 10, 1)
commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals, time.Now())
require.NoError(t, err)
ev := NewMockEvidence(h, time.Now(), valSet.Validators[0].Address)
ev := NewMockDuplicateVoteEvidenceWithValidator(h, time.Now(), vals[0], "block-test-chain")
evList := []Evidence{ev}
partSet := MakeBlock(h, []Tx{Tx("Hello World")}, commit, evList).MakePartSet(512)
assert.NotNil(t, partSet)
assert.EqualValues(t, 3, partSet.Total())
assert.EqualValues(t, 4, partSet.Total())
}
func TestBlockHashesTo(t *testing.T) {
@ -146,7 +146,7 @@ func TestBlockHashesTo(t *testing.T) {
commit, err := MakeCommit(lastID, h-1, 1, voteSet, vals, time.Now())
require.NoError(t, err)
ev := NewMockEvidence(h, time.Now(), valSet.Validators[0].Address)
ev := NewMockDuplicateVoteEvidenceWithValidator(h, time.Now(), vals[0], "block-test-chain")
evList := []Evidence{ev}
block := MakeBlock(h, []Tx{Tx("Hello World")}, commit, evList)
@ -639,7 +639,7 @@ func TestBlockProtoBuf(t *testing.T) {
b2 := MakeBlock(h, []Tx{Tx([]byte{1})}, c1, []Evidence{})
b2.ProposerAddress = tmrand.Bytes(crypto.AddressSize)
evi := NewMockEvidence(b2.Height, time.Now(), tmrand.Bytes(32))
evi := NewMockDuplicateVoteEvidence(h, time.Now(), "block-test-chain")
b2.Evidence = EvidenceData{Evidence: EvidenceList{evi}}
b2.EvidenceHash = b2.Evidence.Hash()


+ 38
- 104
types/evidence.go View File

@ -13,6 +13,7 @@ import (
"github.com/tendermint/tendermint/crypto/tmhash"
tmjson "github.com/tendermint/tendermint/libs/json"
tmmath "github.com/tendermint/tendermint/libs/math"
tmrand "github.com/tendermint/tendermint/libs/rand"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
)
@ -150,39 +151,6 @@ func EvidenceToProto(evidence Evidence) (*tmproto.Evidence, error) {
}
return tp, nil
case MockEvidence:
if err := evi.ValidateBasic(); err != nil {
return nil, err
}
tp := &tmproto.Evidence{
Sum: &tmproto.Evidence_MockEvidence{
MockEvidence: &tmproto.MockEvidence{
EvidenceHeight: evi.Height(),
EvidenceTime: evi.Time(),
EvidenceAddress: evi.Address(),
},
},
}
return tp, nil
case MockRandomEvidence:
if err := evi.ValidateBasic(); err != nil {
return nil, err
}
tp := &tmproto.Evidence{
Sum: &tmproto.Evidence_MockRandomEvidence{
MockRandomEvidence: &tmproto.MockRandomEvidence{
EvidenceHeight: evi.Height(),
EvidenceTime: evi.Time(),
EvidenceAddress: evi.Address(),
RandBytes: evi.randBytes,
},
},
}
return tp, nil
default:
return nil, fmt.Errorf("toproto: evidence is not recognized: %T", evi)
}
@ -206,23 +174,6 @@ func EvidenceFromProto(evidence *tmproto.Evidence) (Evidence, error) {
return AmnesiaEvidenceFromProto(evi.AmnesiaEvidence)
case *tmproto.Evidence_PhantomValidatorEvidence:
return PhantomValidatorEvidenceFromProto(evi.PhantomValidatorEvidence)
case *tmproto.Evidence_MockEvidence:
me := MockEvidence{
EvidenceHeight: evi.MockEvidence.GetEvidenceHeight(),
EvidenceAddress: evi.MockEvidence.GetEvidenceAddress(),
EvidenceTime: evi.MockEvidence.GetEvidenceTime(),
}
return me, me.ValidateBasic()
case *tmproto.Evidence_MockRandomEvidence:
mre := MockRandomEvidence{
MockEvidence: MockEvidence{
EvidenceHeight: evi.MockRandomEvidence.GetEvidenceHeight(),
EvidenceAddress: evi.MockRandomEvidence.GetEvidenceAddress(),
EvidenceTime: evi.MockRandomEvidence.GetEvidenceTime(),
},
randBytes: evi.MockRandomEvidence.RandBytes,
}
return mre, mre.ValidateBasic()
default:
return nil, errors.New("evidence is not recognized")
}
@ -1677,7 +1628,7 @@ func AmnesiaEvidenceFromProto(pb *tmproto.AmnesiaEvidence) (*AmnesiaEvidence, er
return tp, tp.ValidateBasic()
}
//--------------------------------------------------------------
//--------------------------------------------------
// EvidenceList is a list of Evidence. Evidences is not a word.
type EvidenceList []Evidence
@ -1712,69 +1663,52 @@ func (evl EvidenceList) Has(evidence Evidence) bool {
return false
}
//--------------------------------------------------
// UNSTABLE
type MockRandomEvidence struct {
MockEvidence
randBytes []byte
}
//-------------------------------------------- MOCKING --------------------------------------
var _ Evidence = &MockRandomEvidence{}
// unstable - use only for testing
// UNSTABLE
func NewMockRandomEvidence(height int64, eTime time.Time, address []byte, randBytes []byte) MockRandomEvidence {
return MockRandomEvidence{
MockEvidence{
EvidenceHeight: height,
EvidenceTime: eTime,
EvidenceAddress: address}, randBytes,
}
// assumes the round to be 0 and the validator index to be 0
func NewMockDuplicateVoteEvidence(height int64, time time.Time, chainID string) *DuplicateVoteEvidence {
val := NewMockPV()
return NewMockDuplicateVoteEvidenceWithValidator(height, time, val, chainID)
}
func (e MockRandomEvidence) Hash() []byte {
return []byte(fmt.Sprintf("%d-%x", e.EvidenceHeight, e.randBytes))
}
func (e MockRandomEvidence) Equal(ev Evidence) bool { return false }
func NewMockDuplicateVoteEvidenceWithValidator(height int64, time time.Time,
pv PrivValidator, chainID string) *DuplicateVoteEvidence {
pubKey, _ := pv.GetPubKey()
voteA := makeMockVote(height, 0, 0, pubKey.Address(), randBlockID(), time)
vA := voteA.ToProto()
_ = pv.SignVote(chainID, vA)
voteA.Signature = vA.Signature
voteB := makeMockVote(height, 0, 0, pubKey.Address(), randBlockID(), time)
vB := voteB.ToProto()
_ = pv.SignVote(chainID, vB)
voteB.Signature = vB.Signature
return NewDuplicateVoteEvidence(voteA, voteB)
// UNSTABLE
type MockEvidence struct {
EvidenceHeight int64
EvidenceTime time.Time
EvidenceAddress []byte
}
var _ Evidence = &MockEvidence{}
// UNSTABLE
func NewMockEvidence(height int64, eTime time.Time, address []byte) MockEvidence {
return MockEvidence{
EvidenceHeight: height,
EvidenceTime: eTime,
EvidenceAddress: address,
func makeMockVote(height int64, round, index int32, addr Address,
blockID BlockID, time time.Time) *Vote {
return &Vote{
Type: tmproto.SignedMsgType(2),
Height: height,
Round: round,
BlockID: blockID,
Timestamp: time,
ValidatorAddress: addr,
ValidatorIndex: index,
}
}
func (e MockEvidence) Height() int64 { return e.EvidenceHeight }
func (e MockEvidence) Time() time.Time { return e.EvidenceTime }
func (e MockEvidence) Address() []byte { return e.EvidenceAddress }
func (e MockEvidence) Hash() []byte {
return []byte(fmt.Sprintf("%d-%x-%s",
e.EvidenceHeight, e.EvidenceAddress, e.EvidenceTime))
}
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) Equal(ev Evidence) bool {
return e.EvidenceHeight == ev.Height() &&
bytes.Equal(e.EvidenceAddress, ev.Address())
}
func (e MockEvidence) ValidateBasic() error { return nil }
func (e MockEvidence) String() string {
return fmt.Sprintf("Evidence: %d/%s/%s", e.EvidenceHeight, e.Time(), e.EvidenceAddress)
func randBlockID() BlockID {
return BlockID{
Hash: tmrand.Bytes(tmhash.Size),
PartSetHeader: PartSetHeader{
Total: 1,
Hash: tmrand.Bytes(tmhash.Size),
},
}
}
// mock polc - fails validate basic, not stable


+ 2
- 7
types/evidence_test.go View File

@ -201,16 +201,11 @@ func TestDuplicateVoteEvidenceValidation(t *testing.T) {
}
}
func TestMockGoodEvidenceValidateBasic(t *testing.T) {
goodEvidence := NewMockEvidence(int64(1), time.Now(), []byte{1})
func TestMockEvidenceValidateBasic(t *testing.T) {
goodEvidence := NewMockDuplicateVoteEvidence(int64(1), time.Now(), "mock-chain-id")
assert.Nil(t, goodEvidence.ValidateBasic())
}
func TestMockBadEvidenceValidateBasic(t *testing.T) {
badEvidence := NewMockEvidence(int64(1), time.Now(), []byte{1})
assert.Nil(t, badEvidence.ValidateBasic())
}
func TestLunaticValidatorEvidence(t *testing.T) {
var (
blockID = makeBlockIDRandom()


+ 0
- 3
types/protobuf.go View File

@ -139,9 +139,6 @@ func (tm2pb) Evidence(ev Evidence, valSet *ValidatorSet, evTime time.Time) abci.
evType = ABCIEvidenceTypeLunatic
case *PotentialAmnesiaEvidence:
evType = ABCIEvidenceTypePotentialAmnesia
case MockEvidence:
// XXX: not great to have test types in production paths ...
evType = ABCIEvidenceTypeMock
default:
panic(fmt.Sprintf("Unknown evidence type: %v %v", ev, reflect.TypeOf(ev)))
}


Loading…
Cancel
Save