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

This commit is contained in:
Callum Waters
2020-06-24 07:24:30 +02:00
committed by GitHub
parent a2284b8533
commit 3ecc0ffe7e
12 changed files with 199 additions and 1034 deletions

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()

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,71 +1663,54 @@ func (evl EvidenceList) Has(evidence Evidence) bool {
return false
}
//--------------------------------------------------
//-------------------------------------------- MOCKING --------------------------------------
// UNSTABLE
type MockRandomEvidence struct {
MockEvidence
randBytes []byte
// unstable - use only for testing
// 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)
}
var _ Evidence = &MockRandomEvidence{}
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
func NewMockRandomEvidence(height int64, eTime time.Time, address []byte, randBytes []byte) MockRandomEvidence {
return MockRandomEvidence{
MockEvidence{
EvidenceHeight: height,
EvidenceTime: eTime,
EvidenceAddress: address}, randBytes,
}
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 MockRandomEvidence) Hash() []byte {
return []byte(fmt.Sprintf("%d-%x", e.EvidenceHeight, e.randBytes))
}
func (e MockRandomEvidence) Equal(ev Evidence) bool { return false }
// 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 randBlockID() BlockID {
return BlockID{
Hash: tmrand.Bytes(tmhash.Size),
PartSetHeader: PartSetHeader{
Total: 1,
Hash: tmrand.Bytes(tmhash.Size),
},
}
}
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)
}
// mock polc - fails validate basic, not stable
func NewMockPOLC(height int64, time time.Time, pubKey crypto.PubKey) ProofOfLockChange {
voteVal := NewMockPV()

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()

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)))
}