Browse Source

evidence: remove ConflictingHeaders type (#5317)

## Description

Remove ConflictingHeaders & compositeEvidence types


Ref #5288
pull/5318/merge
Marko 4 years ago
committed by GitHub
parent
commit
e0140e4beb
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 129 additions and 1068 deletions
  1. +12
    -4
      CHANGELOG_PENDING.md
  2. +3
    -6
      evidence/doc.go
  3. +45
    -74
      evidence/pool.go
  4. +2
    -33
      light/client.go
  5. +0
    -40
      light/client_test.go
  6. +0
    -17
      light/errors.go
  7. +55
    -382
      proto/tendermint/types/evidence.pb.go
  8. +11
    -17
      proto/tendermint/types/evidence.proto
  9. +0
    -70
      rpc/client/evidence_test.go
  10. +1
    -6
      types/block.go
  11. +0
    -3
      types/block_test.go
  12. +0
    -306
      types/evidence.go
  13. +0
    -110
      types/evidence_test.go

+ 12
- 4
CHANGELOG_PENDING.md View File

@ -6,11 +6,19 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermi
## BREAKING CHANGES
- [crypto/secp256k1] \#5280 `secp256k1` has been removed from the Tendermint repo. (@marbar3778)
- CLI/RPC/Config
- [config] \#5315 Rename `prof_laddr` to `pprof_laddr` and move it to `rpc` section (@melekes)
- [rpc] \#5315 Remove `/unsafe_start_cpu_profiler`, `/unsafe_stop_cpu_profiler` and `/unsafe_write_heap_profile`. Please use pprof functionality instead (@melekes)
- [config] \#5315 Rename `prof_laddr` to `pprof_laddr` and move it to `rpc` section (@melekes)
- [rpc] \#5315 Remove `/unsafe_start_cpu_profiler`, `/unsafe_stop_cpu_profiler` and `/unsafe_write_heap_profile`. Please use pprof functionality instead (@melekes)
- Apps
- P2P Protocol
- Go API
- [evidence] \#5317 Remove ConflictingHeaders evidence type & CompositeEvidence Interface. (@marbar3778)
- [crypto/secp256k1] \#5280 `secp256k1` has been removed from the Tendermint repo. (@marbar3778)
- Blockchain Protocol
## FEATURES


+ 3
- 6
evidence/doc.go View File

@ -10,14 +10,11 @@ go) which operates both the sending and receiving of evidence.
The `Receive` function takes a list of evidence and does the following:
1. Breaks it down into individual evidence if it is `Composite Evidence`
(see types/evidence.go#ConflictingHeadersEvidence)
1. Checks that it does not already have the evidence stored
2. Checks that it does not already have the evidence stored
2. Verifies the evidence against the node's state (see state/validation.go#VerifyEvidence)
3. Verifies the evidence against the node's state (see state/validation.go#VerifyEvidence)
4. Stores the evidence to a db and a concurrent list
3. Stores the evidence to a db and a concurrent list
The gossiping of evidence is initiated when a peer is added which starts a go routine to broadcast currently
uncommitted evidence at intervals of 60 seconds (set by the by broadcastEvidenceIntervalS).


+ 45
- 74
evidence/pool.go View File

@ -142,92 +142,63 @@ func (evpool *Pool) AddPOLC(polc *types.ProofOfLockChange) error {
return evpool.evidenceStore.Set(key, polcBytes)
}
// AddEvidence checks the evidence is valid and adds it to the pool. If
// evidence is composite (ConflictingHeadersEvidence), it will be broken up
// into smaller pieces.
func (evpool *Pool) AddEvidence(evidence types.Evidence) error {
var evList = []types.Evidence{evidence}
evpool.logger.Debug("Attempting to add evidence", "ev", evidence)
valSet, err := evpool.stateDB.LoadValidators(evidence.Height())
if err != nil {
return fmt.Errorf("can't load validators at height #%d: %w", evidence.Height(), err)
// AddEvidence checks the evidence is valid and adds it to the pool.
func (evpool *Pool) AddEvidence(ev types.Evidence) error {
evpool.logger.Debug("Attempting to add evidence", "ev", ev)
if evpool.Has(ev) {
// if it is an amnesia evidence we have but POLC is not absent then
// we should still process it else we loop to the next piece of evidence
if ae, ok := ev.(*types.AmnesiaEvidence); !ok || ae.Polc.IsAbsent() {
return nil
}
}
// Break composite evidence into smaller pieces.
if ce, ok := evidence.(types.CompositeEvidence); ok {
evpool.logger.Info("Breaking up composite evidence", "ev", evidence)
blockMeta := evpool.blockStore.LoadBlockMeta(evidence.Height())
if blockMeta == nil {
return fmt.Errorf("don't have block meta at height #%d", evidence.Height())
}
// 1) Verify against state.
if err := evpool.verify(ev); err != nil {
return types.NewErrEvidenceInvalid(ev, err)
}
if err := ce.VerifyComposite(&blockMeta.Header, valSet); err != nil {
// For potential amnesia evidence, if this node is indicted it shall retrieve a polc
// to form AmensiaEvidence else start the trial period for the piece of evidence
if pe, ok := ev.(*types.PotentialAmnesiaEvidence); ok {
if err := evpool.handleInboundPotentialAmnesiaEvidence(pe); err != nil {
return err
}
evList = ce.Split(&blockMeta.Header, valSet)
}
for _, ev := range evList {
if evpool.Has(ev) {
// if it is an amnesia evidence we have but POLC is not absent then
// we should still process it else we loop to the next piece of evidence
if ae, ok := ev.(*types.AmnesiaEvidence); !ok || ae.Polc.IsAbsent() {
continue
return nil
} else if ae, ok := ev.(*types.AmnesiaEvidence); ok {
// we have received an new amnesia evidence that we have never seen before so we must extract out the
// potential amnesia evidence part and run our own trial
if ae.Polc.IsAbsent() && ae.PotentialAmnesiaEvidence.VoteA.Round <
ae.PotentialAmnesiaEvidence.VoteB.Round {
if err := evpool.handleInboundPotentialAmnesiaEvidence(ae.PotentialAmnesiaEvidence); err != nil {
return fmt.Errorf("failed to handle amnesia evidence, err: %w", err)
}
return nil
}
// 1) Verify against state.
if err := evpool.verify(ev); err != nil {
return types.NewErrEvidenceInvalid(ev, err)
}
// For potential amnesia evidence, if this node is indicted it shall retrieve a polc
// to form AmensiaEvidence else start the trial period for the piece of evidence
if pe, ok := ev.(*types.PotentialAmnesiaEvidence); ok {
if err := evpool.handleInboundPotentialAmnesiaEvidence(pe); err != nil {
return err
}
continue
} else if ae, ok := ev.(*types.AmnesiaEvidence); ok {
// we have received an new amnesia evidence that we have never seen before so we must extract out the
// potential amnesia evidence part and run our own trial
if ae.Polc.IsAbsent() && ae.PotentialAmnesiaEvidence.VoteA.Round <
ae.PotentialAmnesiaEvidence.VoteB.Round {
if err := evpool.handleInboundPotentialAmnesiaEvidence(ae.PotentialAmnesiaEvidence); err != nil {
return fmt.Errorf("failed to handle amnesia evidence, err: %w", err)
}
continue
} else {
// we are going to add this amnesia evidence as it's already punishable.
// We also check if we already have an amnesia evidence or potential
// amnesia evidence that addesses the same case that we will need to remove
aeWithoutPolc := types.NewAmnesiaEvidence(ae.PotentialAmnesiaEvidence, types.NewEmptyPOLC())
if evpool.IsPending(aeWithoutPolc) {
evpool.removePendingEvidence(aeWithoutPolc)
} else if evpool.IsOnTrial(ae.PotentialAmnesiaEvidence) {
key := keyAwaitingTrial(ae.PotentialAmnesiaEvidence)
if err := evpool.evidenceStore.Delete(key); err != nil {
evpool.logger.Error("Failed to remove potential amnesia evidence from database", "err", err)
}
}
// we are going to add this amnesia evidence as it's already punishable.
// We also check if we already have an amnesia evidence or potential
// amnesia evidence that addesses the same case that we will need to remove
aeWithoutPolc := types.NewAmnesiaEvidence(ae.PotentialAmnesiaEvidence, types.NewEmptyPOLC())
if evpool.IsPending(aeWithoutPolc) {
evpool.removePendingEvidence(aeWithoutPolc)
} else if evpool.IsOnTrial(ae.PotentialAmnesiaEvidence) {
key := keyAwaitingTrial(ae.PotentialAmnesiaEvidence)
if err := evpool.evidenceStore.Delete(key); err != nil {
evpool.logger.Error("Failed to remove potential amnesia evidence from database", "err", err)
}
}
}
// 2) Save to store.
if err := evpool.addPendingEvidence(ev); err != nil {
return fmt.Errorf("database error when adding evidence: %v", err)
}
// 2) Save to store.
if err := evpool.addPendingEvidence(ev); err != nil {
return fmt.Errorf("database error when adding evidence: %v", err)
}
// 3) Add evidence to clist.
evpool.evidenceList.PushBack(ev)
// 3) Add evidence to clist.
evpool.evidenceList.PushBack(ev)
evpool.logger.Info("Verified new evidence of byzantine behavior", "evidence", ev)
}
evpool.logger.Info("Verified new evidence of byzantine behavior", "evidence", ev)
return nil
}


+ 2
- 33
light/client.go View File

@ -931,10 +931,7 @@ func (c *Client) compareNewHeaderWithWitnesses(l *types.LightBlock, now time.Tim
defer c.providerMutex.Unlock()
// 1. Make sure AT LEAST ONE witness returns the same header.
var (
headerMatched bool
lastErrConfHeaders error
)
var headerMatched bool
for attempt := uint16(1); attempt <= c.maxRetryAttempts; attempt++ {
if len(c.witnesses) == 0 {
return errNoWitnesses{}
@ -955,10 +952,6 @@ func (c *Client) compareNewHeaderWithWitnesses(l *types.LightBlock, now time.Tim
switch e := err.(type) {
case nil: // at least one header matched
headerMatched = true
case ErrConflictingHeaders: // fork detected
c.logger.Info("FORK DETECTED", "witness", e.Witness, "err", err)
c.sendConflictingHeadersEvidence(&types.ConflictingHeadersEvidence{H1: e.H1, H2: e.H2})
lastErrConfHeaders = e
case errBadWitness:
c.logger.Info("Bad witness", "witness", c.witnesses[e.WitnessIndex], "err", err)
// if witness sent us invalid header / vals, remove it
@ -973,11 +966,7 @@ func (c *Client) compareNewHeaderWithWitnesses(l *types.LightBlock, now time.Tim
c.removeWitness(idx)
}
if lastErrConfHeaders != nil {
// NOTE: all of the potential forks will be reported, but we only return
// the last ErrConflictingHeaders error here.
return lastErrConfHeaders
} else if headerMatched {
if headerMatched {
return nil
}
@ -1003,7 +992,6 @@ func (c *Client) compareNewHeaderWithWitness(errc chan error, l *types.LightBloc
errc <- errBadWitness{bsErr, invalidLightBlock, witnessIndex}
return
}
errc <- ErrConflictingHeaders{H1: l.SignedHeader, Primary: c.primary, H2: altBlock.SignedHeader, Witness: witness}
}
errc <- nil
@ -1120,25 +1108,6 @@ func (c *Client) validateLightBlock(l *types.LightBlock, expectedHeight int64) e
return nil
}
// sendConflictingHeadersEvidence sends evidence to all witnesses and primary
// on best effort basis.
//
// Evidence needs to be submitted to all full nodes since there's no way to
// determine which full node is correct (honest).
func (c *Client) sendConflictingHeadersEvidence(ev *types.ConflictingHeadersEvidence) {
err := c.primary.ReportEvidence(ev)
if err != nil {
c.logger.Error("Failed to report evidence to primary", "ev", ev, "primary", c.primary)
}
for _, w := range c.witnesses {
err := w.ReportEvidence(ev)
if err != nil {
c.logger.Error("Failed to report evidence to witness", "ev", ev, "witness", w)
}
}
}
// exponential backoff (with jitter)
// 0.5s -> 2s -> 4.5s -> 8s -> 12.5 with 1s variation
func backoffTimeout(attempt uint16) time.Duration {


+ 0
- 40
light/client_test.go View File

@ -973,46 +973,6 @@ func TestClient_TrustedValidatorSet(t *testing.T) {
assert.Equal(t, 1, len(c.Witnesses()))
}
func TestClientReportsConflictingHeadersEvidence(t *testing.T) {
// fullNode2 sends us different header
altH2 := keys.GenSignedHeaderLastBlockID(chainID, 2, bTime.Add(30*time.Minute), nil, vals, vals,
hash("app_hash2"), hash("cons_hash"), hash("results_hash"),
0, len(keys), types.BlockID{Hash: h1.Hash()})
fullNode2 := mockp.New(
chainID,
map[int64]*types.SignedHeader{
1: h1,
2: altH2,
},
map[int64]*types.ValidatorSet{
1: vals,
2: vals,
},
)
c, err := light.NewClient(
chainID,
trustOptions,
fullNode,
[]provider.Provider{fullNode2},
dbs.New(dbm.NewMemDB(), chainID),
light.Logger(log.TestingLogger()),
light.MaxRetryAttempts(1),
)
require.NoError(t, err)
// Check verification returns an error.
_, err = c.VerifyLightBlockAtHeight(2, bTime.Add(2*time.Hour))
if assert.Error(t, err) {
assert.Contains(t, err.Error(), "does not match one")
}
// Check evidence was sent to both full nodes.
ev := &types.ConflictingHeadersEvidence{H1: h2, H2: altH2}
assert.True(t, fullNode2.HasEvidence(ev))
assert.True(t, fullNode.HasEvidence(ev))
}
func TestClientPrunesHeadersAndValidatorSets(t *testing.T) {
c, err := light.NewClient(
chainID,


+ 0
- 17
light/errors.go View File

@ -4,7 +4,6 @@ import (
"fmt"
"time"
"github.com/tendermint/tendermint/light/provider"
"github.com/tendermint/tendermint/types"
)
@ -40,22 +39,6 @@ func (e ErrInvalidHeader) Error() string {
return fmt.Sprintf("invalid header: %v", e.Reason)
}
// ErrConflictingHeaders is thrown when two conflicting headers are discovered.
type ErrConflictingHeaders struct {
H1 *types.SignedHeader
Primary provider.Provider
H2 *types.SignedHeader
Witness provider.Provider
}
func (e ErrConflictingHeaders) Error() string {
return fmt.Sprintf(
"header hash %X from primary %v does not match one %X from witness %v",
e.H1.Hash(), e.Primary,
e.H2.Hash(), e.Witness)
}
// ErrVerificationFailed means either sequential or skipping verification has
// failed to verify from header #1 to header #2 due to some reason.
type ErrVerificationFailed struct {


+ 55
- 382
proto/tendermint/types/evidence.pb.go View File

@ -210,58 +210,6 @@ func (m *AmnesiaEvidence) GetPolc() *ProofOfLockChange {
return nil
}
type ConflictingHeadersEvidence struct {
H1 *SignedHeader `protobuf:"bytes,1,opt,name=h1,proto3" json:"h1,omitempty"`
H2 *SignedHeader `protobuf:"bytes,2,opt,name=h2,proto3" json:"h2,omitempty"`
}
func (m *ConflictingHeadersEvidence) Reset() { *m = ConflictingHeadersEvidence{} }
func (m *ConflictingHeadersEvidence) String() string { return proto.CompactTextString(m) }
func (*ConflictingHeadersEvidence) ProtoMessage() {}
func (*ConflictingHeadersEvidence) Descriptor() ([]byte, []int) {
return fileDescriptor_6825fabc78e0a168, []int{3}
}
func (m *ConflictingHeadersEvidence) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
}
func (m *ConflictingHeadersEvidence) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
if deterministic {
return xxx_messageInfo_ConflictingHeadersEvidence.Marshal(b, m, deterministic)
} else {
b = b[:cap(b)]
n, err := m.MarshalToSizedBuffer(b)
if err != nil {
return nil, err
}
return b[:n], nil
}
}
func (m *ConflictingHeadersEvidence) XXX_Merge(src proto.Message) {
xxx_messageInfo_ConflictingHeadersEvidence.Merge(m, src)
}
func (m *ConflictingHeadersEvidence) XXX_Size() int {
return m.Size()
}
func (m *ConflictingHeadersEvidence) XXX_DiscardUnknown() {
xxx_messageInfo_ConflictingHeadersEvidence.DiscardUnknown(m)
}
var xxx_messageInfo_ConflictingHeadersEvidence proto.InternalMessageInfo
func (m *ConflictingHeadersEvidence) GetH1() *SignedHeader {
if m != nil {
return m.H1
}
return nil
}
func (m *ConflictingHeadersEvidence) GetH2() *SignedHeader {
if m != nil {
return m.H2
}
return nil
}
type LunaticValidatorEvidence struct {
Header *Header `protobuf:"bytes,1,opt,name=header,proto3" json:"header,omitempty"`
Vote *Vote `protobuf:"bytes,2,opt,name=vote,proto3" json:"vote,omitempty"`
@ -273,7 +221,7 @@ func (m *LunaticValidatorEvidence) Reset() { *m = LunaticValidatorEviden
func (m *LunaticValidatorEvidence) String() string { return proto.CompactTextString(m) }
func (*LunaticValidatorEvidence) ProtoMessage() {}
func (*LunaticValidatorEvidence) Descriptor() ([]byte, []int) {
return fileDescriptor_6825fabc78e0a168, []int{4}
return fileDescriptor_6825fabc78e0a168, []int{3}
}
func (m *LunaticValidatorEvidence) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -333,7 +281,6 @@ func (m *LunaticValidatorEvidence) GetTimestamp() time.Time {
type Evidence struct {
// Types that are valid to be assigned to Sum:
// *Evidence_DuplicateVoteEvidence
// *Evidence_ConflictingHeadersEvidence
// *Evidence_LunaticValidatorEvidence
// *Evidence_PotentialAmnesiaEvidence
// *Evidence_AmnesiaEvidence
@ -344,7 +291,7 @@ func (m *Evidence) Reset() { *m = Evidence{} }
func (m *Evidence) String() string { return proto.CompactTextString(m) }
func (*Evidence) ProtoMessage() {}
func (*Evidence) Descriptor() ([]byte, []int) {
return fileDescriptor_6825fabc78e0a168, []int{5}
return fileDescriptor_6825fabc78e0a168, []int{4}
}
func (m *Evidence) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -382,9 +329,6 @@ type isEvidence_Sum interface {
type Evidence_DuplicateVoteEvidence struct {
DuplicateVoteEvidence *DuplicateVoteEvidence `protobuf:"bytes,1,opt,name=duplicate_vote_evidence,json=duplicateVoteEvidence,proto3,oneof" json:"duplicate_vote_evidence,omitempty"`
}
type Evidence_ConflictingHeadersEvidence struct {
ConflictingHeadersEvidence *ConflictingHeadersEvidence `protobuf:"bytes,2,opt,name=conflicting_headers_evidence,json=conflictingHeadersEvidence,proto3,oneof" json:"conflicting_headers_evidence,omitempty"`
}
type Evidence_LunaticValidatorEvidence struct {
LunaticValidatorEvidence *LunaticValidatorEvidence `protobuf:"bytes,3,opt,name=lunatic_validator_evidence,json=lunaticValidatorEvidence,proto3,oneof" json:"lunatic_validator_evidence,omitempty"`
}
@ -395,11 +339,10 @@ type Evidence_AmnesiaEvidence struct {
AmnesiaEvidence *AmnesiaEvidence `protobuf:"bytes,5,opt,name=amnesia_evidence,json=amnesiaEvidence,proto3,oneof" json:"amnesia_evidence,omitempty"`
}
func (*Evidence_DuplicateVoteEvidence) isEvidence_Sum() {}
func (*Evidence_ConflictingHeadersEvidence) isEvidence_Sum() {}
func (*Evidence_LunaticValidatorEvidence) isEvidence_Sum() {}
func (*Evidence_PotentialAmnesiaEvidence) isEvidence_Sum() {}
func (*Evidence_AmnesiaEvidence) isEvidence_Sum() {}
func (*Evidence_DuplicateVoteEvidence) isEvidence_Sum() {}
func (*Evidence_LunaticValidatorEvidence) isEvidence_Sum() {}
func (*Evidence_PotentialAmnesiaEvidence) isEvidence_Sum() {}
func (*Evidence_AmnesiaEvidence) isEvidence_Sum() {}
func (m *Evidence) GetSum() isEvidence_Sum {
if m != nil {
@ -415,13 +358,6 @@ func (m *Evidence) GetDuplicateVoteEvidence() *DuplicateVoteEvidence {
return nil
}
func (m *Evidence) GetConflictingHeadersEvidence() *ConflictingHeadersEvidence {
if x, ok := m.GetSum().(*Evidence_ConflictingHeadersEvidence); ok {
return x.ConflictingHeadersEvidence
}
return nil
}
func (m *Evidence) GetLunaticValidatorEvidence() *LunaticValidatorEvidence {
if x, ok := m.GetSum().(*Evidence_LunaticValidatorEvidence); ok {
return x.LunaticValidatorEvidence
@ -447,7 +383,6 @@ func (m *Evidence) GetAmnesiaEvidence() *AmnesiaEvidence {
func (*Evidence) XXX_OneofWrappers() []interface{} {
return []interface{}{
(*Evidence_DuplicateVoteEvidence)(nil),
(*Evidence_ConflictingHeadersEvidence)(nil),
(*Evidence_LunaticValidatorEvidence)(nil),
(*Evidence_PotentialAmnesiaEvidence)(nil),
(*Evidence_AmnesiaEvidence)(nil),
@ -464,7 +399,7 @@ func (m *EvidenceData) Reset() { *m = EvidenceData{} }
func (m *EvidenceData) String() string { return proto.CompactTextString(m) }
func (*EvidenceData) ProtoMessage() {}
func (*EvidenceData) Descriptor() ([]byte, []int) {
return fileDescriptor_6825fabc78e0a168, []int{6}
return fileDescriptor_6825fabc78e0a168, []int{5}
}
func (m *EvidenceData) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -516,7 +451,7 @@ func (m *ProofOfLockChange) Reset() { *m = ProofOfLockChange{} }
func (m *ProofOfLockChange) String() string { return proto.CompactTextString(m) }
func (*ProofOfLockChange) ProtoMessage() {}
func (*ProofOfLockChange) Descriptor() ([]byte, []int) {
return fileDescriptor_6825fabc78e0a168, []int{7}
return fileDescriptor_6825fabc78e0a168, []int{6}
}
func (m *ProofOfLockChange) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@ -563,7 +498,6 @@ func init() {
proto.RegisterType((*DuplicateVoteEvidence)(nil), "tendermint.types.DuplicateVoteEvidence")
proto.RegisterType((*PotentialAmnesiaEvidence)(nil), "tendermint.types.PotentialAmnesiaEvidence")
proto.RegisterType((*AmnesiaEvidence)(nil), "tendermint.types.AmnesiaEvidence")
proto.RegisterType((*ConflictingHeadersEvidence)(nil), "tendermint.types.ConflictingHeadersEvidence")
proto.RegisterType((*LunaticValidatorEvidence)(nil), "tendermint.types.LunaticValidatorEvidence")
proto.RegisterType((*Evidence)(nil), "tendermint.types.Evidence")
proto.RegisterType((*EvidenceData)(nil), "tendermint.types.EvidenceData")
@ -573,52 +507,48 @@ func init() {
func init() { proto.RegisterFile("tendermint/types/evidence.proto", fileDescriptor_6825fabc78e0a168) }
var fileDescriptor_6825fabc78e0a168 = []byte{
// 710 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x55, 0xc1, 0x4e, 0xdb, 0x4a,
0x14, 0xb5, 0x89, 0xc9, 0x83, 0x01, 0x09, 0x9e, 0x05, 0xef, 0x59, 0x16, 0x72, 0x4a, 0xba, 0x68,
0x85, 0xa8, 0x0d, 0x54, 0x15, 0x9b, 0x6e, 0x08, 0xb4, 0x8a, 0x04, 0x6a, 0xa9, 0xa9, 0x58, 0x74,
0xe3, 0x8e, 0xed, 0x89, 0x3d, 0xe0, 0x78, 0xac, 0x78, 0x1c, 0x35, 0x52, 0xbf, 0xa1, 0xe2, 0x63,
0xba, 0xe9, 0x1f, 0xb0, 0x64, 0xd9, 0x55, 0xa9, 0x60, 0xdf, 0x6f, 0xa8, 0x3c, 0x1e, 0xdb, 0x10,
0xc7, 0xa0, 0x56, 0x55, 0x37, 0x91, 0x33, 0xf7, 0xdc, 0x7b, 0xee, 0x99, 0x39, 0x77, 0x06, 0xb4,
0x28, 0x0a, 0x5d, 0x34, 0xe8, 0xe3, 0x90, 0x1a, 0x74, 0x14, 0xa1, 0xd8, 0x40, 0x43, 0xec, 0xa2,
0xd0, 0x41, 0x7a, 0x34, 0x20, 0x94, 0xc8, 0x8b, 0x25, 0x40, 0x67, 0x00, 0x75, 0xc9, 0x23, 0x1e,
0x61, 0x41, 0x23, 0xfd, 0xca, 0x70, 0x6a, 0xcb, 0x23, 0xc4, 0x0b, 0x90, 0xc1, 0xfe, 0xd9, 0x49,
0xcf, 0xa0, 0xb8, 0x8f, 0x62, 0x0a, 0xfb, 0x11, 0x07, 0xac, 0x54, 0x98, 0xd8, 0xef, 0x84, 0xa8,
0x33, 0x18, 0x45, 0x94, 0x18, 0xa7, 0x68, 0xc4, 0xa3, 0xed, 0x2f, 0x22, 0x58, 0xde, 0x4b, 0xa2,
0x00, 0x3b, 0x90, 0xa2, 0x63, 0x42, 0xd1, 0x0b, 0xde, 0xa4, 0xfc, 0x04, 0x34, 0x87, 0x84, 0x22,
0x0b, 0x2a, 0xe2, 0x03, 0xf1, 0xf1, 0xdc, 0xd6, 0x7f, 0xfa, 0x78, 0xbf, 0x7a, 0x8a, 0x37, 0xa7,
0x53, 0xd4, 0x4e, 0x01, 0xb7, 0x95, 0xa9, 0xfb, 0xe1, 0x1d, 0xb9, 0x03, 0x66, 0x0b, 0x19, 0x4a,
0x83, 0x65, 0xa8, 0x7a, 0x26, 0x54, 0xcf, 0x85, 0xea, 0x6f, 0x73, 0x44, 0x67, 0xe6, 0xfc, 0x5b,
0x4b, 0x38, 0xbb, 0x6c, 0x89, 0x66, 0x99, 0xd6, 0xbe, 0x14, 0x81, 0x72, 0x48, 0x28, 0x0a, 0x29,
0x86, 0xc1, 0x4e, 0x3f, 0x44, 0x31, 0x86, 0x7f, 0xa9, 0xfd, 0x55, 0x30, 0xef, 0x23, 0xec, 0xf9,
0xd4, 0x2a, 0x15, 0x34, 0xcc, 0xb9, 0x6c, 0xed, 0x28, 0x5d, 0xba, 0xad, 0x50, 0xfa, 0x3d, 0x85,
0x9f, 0x45, 0xb0, 0x30, 0x2e, 0xcc, 0x07, 0x6a, 0x94, 0x8b, 0xb6, 0x60, 0x16, 0xb4, 0x72, 0x6b,
0x71, 0xb1, 0x6b, 0xd5, 0xee, 0xeb, 0x36, 0xca, 0x54, 0xa2, 0xba, 0x2d, 0xdc, 0x06, 0x52, 0x44,
0x02, 0x87, 0xef, 0xc8, 0xc3, 0x09, 0x35, 0x07, 0x84, 0xf4, 0x5e, 0xf7, 0x0e, 0x88, 0x73, 0xba,
0xeb, 0xc3, 0xd0, 0x43, 0x26, 0x4b, 0x68, 0x7f, 0x04, 0xea, 0x2e, 0x09, 0x7b, 0x01, 0x76, 0x28,
0x0e, 0xbd, 0x2e, 0x82, 0x2e, 0x1a, 0xc4, 0x45, 0x59, 0x1d, 0x4c, 0xf9, 0x9b, 0xbc, 0x51, 0xad,
0x5a, 0xf4, 0x08, 0x7b, 0x21, 0x72, 0xb3, 0x24, 0x73, 0xca, 0xdf, 0x64, 0xf8, 0x2d, 0xde, 0xc4,
0xfd, 0xf8, 0xad, 0xf6, 0x0f, 0x11, 0x28, 0x07, 0x49, 0x08, 0x29, 0x76, 0x8e, 0x61, 0x80, 0x5d,
0x48, 0xc9, 0xa0, 0x20, 0xdf, 0x00, 0x4d, 0x9f, 0x41, 0x79, 0x03, 0x4a, 0xb5, 0x20, 0x2f, 0xc5,
0x71, 0xf2, 0x1a, 0x90, 0xd2, 0x33, 0xbf, 0xc7, 0x17, 0x0c, 0x23, 0x6f, 0x80, 0x25, 0x1c, 0x0e,
0x53, 0x52, 0x2b, 0xcb, 0xb6, 0x7a, 0x18, 0x05, 0x2e, 0xb3, 0xc7, 0xac, 0x29, 0xf3, 0x58, 0x46,
0xf0, 0x32, 0x8d, 0xfc, 0x11, 0x97, 0x7c, 0x92, 0xc0, 0x4c, 0x21, 0x10, 0x82, 0xff, 0xdd, 0x7c,
0x9e, 0x2d, 0x66, 0xe9, 0x31, 0x6f, 0x3c, 0xaa, 0x2a, 0x98, 0x78, 0x01, 0x74, 0x05, 0x73, 0xd9,
0x9d, 0x78, 0x33, 0x44, 0x60, 0xc5, 0x29, 0x8f, 0x97, 0x2b, 0x8d, 0x4b, 0x9e, 0x6c, 0xa7, 0xd6,
0xab, 0x3c, 0xf5, 0xa6, 0xe8, 0x0a, 0xa6, 0xea, 0xd4, 0x5b, 0xe6, 0x04, 0xa8, 0x41, 0x76, 0xa2,
0xd6, 0x30, 0x3f, 0xd2, 0x92, 0xaf, 0x51, 0xe7, 0xf9, 0x3a, 0x17, 0x74, 0x05, 0x53, 0x09, 0xea,
0x1c, 0x72, 0x72, 0xe7, 0x7c, 0x49, 0xbf, 0x3a, 0x5f, 0x29, 0x57, 0xed, 0x84, 0xbd, 0x02, 0x8b,
0x15, 0x86, 0x69, 0xc6, 0xb0, 0x5a, 0x65, 0xa8, 0x16, 0x5e, 0x80, 0xb7, 0x97, 0x3a, 0xd3, 0xa0,
0x11, 0x27, 0xfd, 0xf6, 0x7b, 0x30, 0x9f, 0x2f, 0xed, 0x41, 0x0a, 0xe5, 0xe7, 0x60, 0xe6, 0x86,
0x09, 0x1a, 0xcc, 0x63, 0x95, 0xf2, 0x45, 0x11, 0x29, 0xf5, 0x98, 0x59, 0x64, 0xc8, 0x32, 0x90,
0x7c, 0x18, 0xfb, 0xec, 0x58, 0xe7, 0x4d, 0xf6, 0xdd, 0xfe, 0x00, 0xfe, 0xad, 0x0c, 0xbf, 0xbc,
0x0e, 0xd8, 0xed, 0x18, 0x73, 0x8e, 0x3b, 0xaf, 0xd0, 0x58, 0x7e, 0x06, 0xfe, 0x89, 0x12, 0xdb,
0x3a, 0x45, 0x23, 0x6e, 0x98, 0x95, 0x9b, 0xf8, 0xec, 0xa5, 0xd2, 0x0f, 0x13, 0x3b, 0xc0, 0xce,
0x3e, 0x1a, 0x99, 0xcd, 0x28, 0xb1, 0xf7, 0xd1, 0xa8, 0xf3, 0xe6, 0xfc, 0x4a, 0x13, 0x2f, 0xae,
0x34, 0xf1, 0xfb, 0x95, 0x26, 0x9e, 0x5d, 0x6b, 0xc2, 0xc5, 0xb5, 0x26, 0x7c, 0xbd, 0xd6, 0x84,
0x77, 0xdb, 0x1e, 0xa6, 0x7e, 0x62, 0xeb, 0x0e, 0xe9, 0x1b, 0x37, 0x5f, 0xc4, 0xf2, 0x33, 0x7b,
0x5a, 0xc7, 0x5f, 0x4b, 0xbb, 0xc9, 0xd6, 0x9f, 0xfe, 0x0c, 0x00, 0x00, 0xff, 0xff, 0x84, 0x99,
0x61, 0x70, 0xb2, 0x07, 0x00, 0x00,
// 641 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x55, 0x4f, 0x4f, 0xd4, 0x40,
0x14, 0xdf, 0xba, 0xcb, 0x0a, 0x0f, 0x12, 0xb0, 0x01, 0x6d, 0x36, 0x64, 0x57, 0xd6, 0x83, 0x86,
0x68, 0x4b, 0x34, 0x86, 0x8b, 0x17, 0x56, 0x34, 0x24, 0x10, 0xc5, 0xd1, 0x70, 0xf0, 0x52, 0xa7,
0xed, 0x6c, 0x3b, 0xd0, 0x76, 0x9a, 0x76, 0xba, 0xb1, 0xdf, 0x82, 0x0f, 0xe0, 0xc7, 0xf0, 0xe2,
0x37, 0xe0, 0xc8, 0xd1, 0x93, 0x18, 0xb8, 0xfb, 0x19, 0x4c, 0xa7, 0x7f, 0x16, 0xb6, 0x5b, 0x88,
0xc6, 0x78, 0xd9, 0x74, 0xdf, 0xfb, 0xbd, 0x3f, 0xbf, 0xf7, 0x7b, 0x33, 0x03, 0x3d, 0x4e, 0x7c,
0x8b, 0x84, 0x1e, 0xf5, 0xb9, 0xc6, 0x93, 0x80, 0x44, 0x1a, 0x19, 0x51, 0x8b, 0xf8, 0x26, 0x51,
0x83, 0x90, 0x71, 0x26, 0x2f, 0x8d, 0x01, 0xaa, 0x00, 0x74, 0x96, 0x6d, 0x66, 0x33, 0xe1, 0xd4,
0xd2, 0xaf, 0x0c, 0xd7, 0xe9, 0xd9, 0x8c, 0xd9, 0x2e, 0xd1, 0xc4, 0x3f, 0x23, 0x1e, 0x6a, 0x9c,
0x7a, 0x24, 0xe2, 0xd8, 0x0b, 0x72, 0xc0, 0x6a, 0xa5, 0x92, 0xf8, 0x9d, 0xe2, 0x35, 0xc3, 0x24,
0xe0, 0x4c, 0x3b, 0x22, 0x49, 0xee, 0xed, 0x7f, 0x93, 0x60, 0x65, 0x3b, 0x0e, 0x5c, 0x6a, 0x62,
0x4e, 0x0e, 0x18, 0x27, 0xaf, 0xf2, 0x26, 0xe5, 0x27, 0xd0, 0x1e, 0x31, 0x4e, 0x74, 0xac, 0x48,
0xf7, 0xa5, 0x47, 0xf3, 0x4f, 0xef, 0xaa, 0x93, 0xfd, 0xaa, 0x29, 0x1e, 0xcd, 0xa4, 0xa8, 0xad,
0x12, 0x6e, 0x28, 0xb7, 0x6e, 0x86, 0x0f, 0xe4, 0x01, 0xcc, 0x95, 0x34, 0x94, 0xa6, 0x88, 0xe8,
0xa8, 0x19, 0x51, 0xb5, 0x20, 0xaa, 0x7e, 0x28, 0x10, 0x83, 0xd9, 0x93, 0x1f, 0xbd, 0xc6, 0xf1,
0x59, 0x4f, 0x42, 0xe3, 0xb0, 0xfe, 0x99, 0x04, 0xca, 0x3e, 0xe3, 0xc4, 0xe7, 0x14, 0xbb, 0x5b,
0x9e, 0x4f, 0x22, 0x8a, 0xff, 0x53, 0xfb, 0x6b, 0xb0, 0xe0, 0x10, 0x6a, 0x3b, 0x5c, 0x1f, 0x33,
0x68, 0xa2, 0xf9, 0xcc, 0xf6, 0x3e, 0x35, 0x5d, 0x65, 0xd8, 0xfa, 0x3b, 0x86, 0x5f, 0x25, 0x58,
0x9c, 0x24, 0xe6, 0x40, 0x27, 0x28, 0x48, 0xeb, 0x38, 0x73, 0xea, 0xc5, 0x6a, 0xe5, 0x64, 0xd7,
0xab, 0xdd, 0xd7, 0x0d, 0x0a, 0x29, 0x41, 0xdd, 0x08, 0x37, 0xa1, 0x15, 0x30, 0xd7, 0xcc, 0x27,
0xf2, 0x60, 0x4a, 0xce, 0x90, 0xb1, 0xe1, 0xdb, 0xe1, 0x1e, 0x33, 0x8f, 0x5e, 0x3a, 0xd8, 0xb7,
0x09, 0x12, 0x01, 0xfd, 0x5f, 0x12, 0x28, 0x7b, 0xb1, 0x8f, 0x39, 0x35, 0x0f, 0xb0, 0x4b, 0x2d,
0xcc, 0x59, 0x58, 0x66, 0xdd, 0x80, 0xb6, 0x43, 0xb0, 0x45, 0xc2, 0xbc, 0x57, 0xa5, 0x9a, 0x77,
0x47, 0xf8, 0x51, 0x8e, 0x93, 0xd7, 0xa1, 0x95, 0x4e, 0xfd, 0x06, 0x65, 0x04, 0x46, 0xde, 0x80,
0x65, 0xea, 0x8f, 0xd2, 0xa2, 0x7a, 0x16, 0xad, 0x0f, 0x29, 0x71, 0x2d, 0x21, 0xd0, 0x1c, 0x92,
0x73, 0x5f, 0x56, 0xe0, 0x75, 0xea, 0xf9, 0x27, 0x3a, 0x7d, 0x69, 0xc2, 0x6c, 0x49, 0x10, 0xc3,
0x3d, 0xab, 0x38, 0x51, 0xba, 0x58, 0xaa, 0x09, 0x75, 0x1e, 0x56, 0x19, 0x4c, 0x3d, 0x82, 0x3b,
0x0d, 0xb4, 0x62, 0x4d, 0x3d, 0x9b, 0x87, 0xd0, 0x71, 0xb3, 0xf9, 0xea, 0xa3, 0x62, 0xc0, 0xe3,
0x2a, 0xcd, 0xba, 0x1d, 0xa8, 0xd3, 0x64, 0xa7, 0x81, 0x14, 0xb7, 0x4e, 0xaf, 0xc3, 0x6b, 0xf7,
0xad, 0xf5, 0xa7, 0xfb, 0x96, 0xd6, 0xaa, 0xdd, 0xb8, 0x37, 0xb0, 0x54, 0xa9, 0x30, 0x23, 0x2a,
0xac, 0x55, 0x2b, 0x54, 0x13, 0x2f, 0xe2, 0xab, 0xa6, 0xc1, 0x0c, 0x34, 0xa3, 0xd8, 0xeb, 0x7f,
0x82, 0x85, 0xc2, 0xb4, 0x8d, 0x39, 0x96, 0x5f, 0xc0, 0xec, 0x25, 0x49, 0x9a, 0x42, 0xf1, 0x4a,
0xfa, 0x32, 0x49, 0x2b, 0x55, 0x1c, 0x95, 0x11, 0xb2, 0x0c, 0x2d, 0x07, 0x47, 0x8e, 0x58, 0xc7,
0x05, 0x24, 0xbe, 0xfb, 0x9f, 0xe1, 0x4e, 0xe5, 0x30, 0xc8, 0x8f, 0x41, 0xdc, 0x16, 0x51, 0x5e,
0xe3, 0xda, 0x2b, 0x25, 0x92, 0x9f, 0xc3, 0xed, 0x20, 0x36, 0xf4, 0x23, 0x92, 0xe4, 0x8b, 0xbe,
0x7a, 0x19, 0x9f, 0xdd, 0xdc, 0xea, 0x7e, 0x6c, 0xb8, 0xd4, 0xdc, 0x25, 0x09, 0x6a, 0x07, 0xb1,
0xb1, 0x4b, 0x92, 0xc1, 0xbb, 0x93, 0xf3, 0xae, 0x74, 0x7a, 0xde, 0x95, 0x7e, 0x9e, 0x77, 0xa5,
0xe3, 0x8b, 0x6e, 0xe3, 0xf4, 0xa2, 0xdb, 0xf8, 0x7e, 0xd1, 0x6d, 0x7c, 0xdc, 0xb4, 0x29, 0x77,
0x62, 0x43, 0x35, 0x99, 0xa7, 0x5d, 0x7e, 0x21, 0xc6, 0x9f, 0xd9, 0x53, 0x33, 0xf9, 0x7a, 0x18,
0x6d, 0x61, 0x7f, 0xf6, 0x3b, 0x00, 0x00, 0xff, 0xff, 0xc0, 0x2a, 0xcf, 0x0c, 0xc2, 0x06, 0x00,
0x00,
}
func (m *DuplicateVoteEvidence) Marshal() (dAtA []byte, err error) {
@ -783,53 +713,6 @@ func (m *AmnesiaEvidence) MarshalToSizedBuffer(dAtA []byte) (int, error) {
return len(dAtA) - i, nil
}
func (m *ConflictingHeadersEvidence) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
n, err := m.MarshalToSizedBuffer(dAtA[:size])
if err != nil {
return nil, err
}
return dAtA[:n], nil
}
func (m *ConflictingHeadersEvidence) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *ConflictingHeadersEvidence) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
_ = i
var l int
_ = l
if m.H2 != nil {
{
size, err := m.H2.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintEvidence(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x12
}
if m.H1 != nil {
{
size, err := m.H1.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintEvidence(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0xa
}
return len(dAtA) - i, nil
}
func (m *LunaticValidatorEvidence) Marshal() (dAtA []byte, err error) {
size := m.Size()
dAtA = make([]byte, size)
@ -850,12 +733,12 @@ func (m *LunaticValidatorEvidence) MarshalToSizedBuffer(dAtA []byte) (int, error
_ = i
var l int
_ = l
n11, err11 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):])
if err11 != nil {
return 0, err11
n9, err9 := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Timestamp, dAtA[i-github_com_gogo_protobuf_types.SizeOfStdTime(m.Timestamp):])
if err9 != nil {
return 0, err9
}
i -= n11
i = encodeVarintEvidence(dAtA, i, uint64(n11))
i -= n9
i = encodeVarintEvidence(dAtA, i, uint64(n9))
i--
dAtA[i] = 0x22
if len(m.InvalidHeaderField) > 0 {
@ -945,27 +828,6 @@ func (m *Evidence_DuplicateVoteEvidence) MarshalToSizedBuffer(dAtA []byte) (int,
}
return len(dAtA) - i, nil
}
func (m *Evidence_ConflictingHeadersEvidence) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
}
func (m *Evidence_ConflictingHeadersEvidence) MarshalToSizedBuffer(dAtA []byte) (int, error) {
i := len(dAtA)
if m.ConflictingHeadersEvidence != nil {
{
size, err := m.ConflictingHeadersEvidence.MarshalToSizedBuffer(dAtA[:i])
if err != nil {
return 0, err
}
i -= size
i = encodeVarintEvidence(dAtA, i, uint64(size))
}
i--
dAtA[i] = 0x12
}
return len(dAtA) - i, nil
}
func (m *Evidence_LunaticValidatorEvidence) MarshalTo(dAtA []byte) (int, error) {
size := m.Size()
return m.MarshalToSizedBuffer(dAtA[:size])
@ -1191,23 +1053,6 @@ func (m *AmnesiaEvidence) Size() (n int) {
return n
}
func (m *ConflictingHeadersEvidence) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.H1 != nil {
l = m.H1.Size()
n += 1 + l + sovEvidence(uint64(l))
}
if m.H2 != nil {
l = m.H2.Size()
n += 1 + l + sovEvidence(uint64(l))
}
return n
}
func (m *LunaticValidatorEvidence) Size() (n int) {
if m == nil {
return 0
@ -1255,18 +1100,6 @@ func (m *Evidence_DuplicateVoteEvidence) Size() (n int) {
}
return n
}
func (m *Evidence_ConflictingHeadersEvidence) Size() (n int) {
if m == nil {
return 0
}
var l int
_ = l
if m.ConflictingHeadersEvidence != nil {
l = m.ConflictingHeadersEvidence.Size()
n += 1 + l + sovEvidence(uint64(l))
}
return n
}
func (m *Evidence_LunaticValidatorEvidence) Size() (n int) {
if m == nil {
return 0
@ -1807,131 +1640,6 @@ func (m *AmnesiaEvidence) Unmarshal(dAtA []byte) error {
}
return nil
}
func (m *ConflictingHeadersEvidence) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
for iNdEx < l {
preIndex := iNdEx
var wire uint64
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEvidence
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
wire |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: ConflictingHeadersEvidence: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: ConflictingHeadersEvidence: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum {
case 1:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field H1", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEvidence
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthEvidence
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthEvidence
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.H1 == nil {
m.H1 = &SignedHeader{}
}
if err := m.H1.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field H2", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEvidence
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthEvidence
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthEvidence
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
if m.H2 == nil {
m.H2 = &SignedHeader{}
}
if err := m.H2.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
iNdEx = postIndex
default:
iNdEx = preIndex
skippy, err := skipEvidence(dAtA[iNdEx:])
if err != nil {
return err
}
if skippy < 0 {
return ErrInvalidLengthEvidence
}
if (iNdEx + skippy) < 0 {
return ErrInvalidLengthEvidence
}
if (iNdEx + skippy) > l {
return io.ErrUnexpectedEOF
}
iNdEx += skippy
}
}
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil
}
func (m *LunaticValidatorEvidence) Unmarshal(dAtA []byte) error {
l := len(dAtA)
iNdEx := 0
@ -2186,41 +1894,6 @@ func (m *Evidence) Unmarshal(dAtA []byte) error {
}
m.Sum = &Evidence_DuplicateVoteEvidence{v}
iNdEx = postIndex
case 2:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field ConflictingHeadersEvidence", wireType)
}
var msglen int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEvidence
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
msglen |= int(b&0x7F) << shift
if b < 0x80 {
break
}
}
if msglen < 0 {
return ErrInvalidLengthEvidence
}
postIndex := iNdEx + msglen
if postIndex < 0 {
return ErrInvalidLengthEvidence
}
if postIndex > l {
return io.ErrUnexpectedEOF
}
v := &ConflictingHeadersEvidence{}
if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
return err
}
m.Sum = &Evidence_ConflictingHeadersEvidence{v}
iNdEx = postIndex
case 3:
if wireType != 2 {
return fmt.Errorf("proto: wrong wireType = %d for field LunaticValidatorEvidence", wireType)


+ 11
- 17
proto/tendermint/types/evidence.proto View File

@ -13,18 +13,18 @@ import "tendermint/crypto/keys.proto";
message DuplicateVoteEvidence {
Vote vote_a = 1;
Vote vote_b = 2;
google.protobuf.Timestamp timestamp = 3
[(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
[(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
}
message PotentialAmnesiaEvidence {
Vote vote_a = 1;
Vote vote_b = 2;
int64 height_stamp = 3;
google.protobuf.Timestamp timestamp = 4
[(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
int64 height_stamp = 3;
google.protobuf.Timestamp timestamp = 4
[(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
}
message AmnesiaEvidence {
@ -32,27 +32,21 @@ message AmnesiaEvidence {
ProofOfLockChange polc = 2;
}
message ConflictingHeadersEvidence {
SignedHeader h1 = 1;
SignedHeader h2 = 2;
}
message LunaticValidatorEvidence {
Header header = 1;
Vote vote = 2;
string invalid_header_field = 3;
google.protobuf.Timestamp timestamp = 4
[(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
[(gogoproto.nullable) = false, (gogoproto.stdtime) = true];
}
message Evidence {
oneof sum {
DuplicateVoteEvidence duplicate_vote_evidence = 1;
ConflictingHeadersEvidence conflicting_headers_evidence = 2;
LunaticValidatorEvidence lunatic_validator_evidence = 3;
PotentialAmnesiaEvidence potential_amnesia_evidence = 4;
AmnesiaEvidence amnesia_evidence = 5;
DuplicateVoteEvidence duplicate_vote_evidence = 1;
LunaticValidatorEvidence lunatic_validator_evidence = 2;
PotentialAmnesiaEvidence potential_amnesia_evidence = 3;
AmnesiaEvidence amnesia_evidence = 4;
}
}


+ 0
- 70
rpc/client/evidence_test.go View File

@ -9,7 +9,6 @@ import (
"github.com/stretchr/testify/require"
abci "github.com/tendermint/tendermint/abci/types"
"github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/ed25519"
cryptoenc "github.com/tendermint/tendermint/crypto/encoding"
"github.com/tendermint/tendermint/crypto/tmhash"
@ -155,75 +154,6 @@ func TestBroadcastEvidence_DuplicateVoteEvidence(t *testing.T) {
}
}
func TestBroadcastEvidence_ConflictingHeadersEvidence(t *testing.T) {
var (
config = rpctest.GetConfig()
chainID = config.ChainID()
pv = privval.LoadOrGenFilePV(config.PrivValidatorKeyFile(), config.PrivValidatorStateFile())
)
for i, c := range GetClients() {
t.Logf("client %d", i)
h1, err := c.Commit(nil)
require.NoError(t, err)
require.NotNil(t, h1.SignedHeader.Header)
// Create an alternative header with a different AppHash.
h2 := &types.SignedHeader{
Header: &types.Header{
Version: h1.Version,
ChainID: h1.ChainID,
Height: h1.Height,
Time: h1.Time,
LastBlockID: h1.LastBlockID,
LastCommitHash: h1.LastCommitHash,
DataHash: h1.DataHash,
ValidatorsHash: h1.ValidatorsHash,
NextValidatorsHash: h1.NextValidatorsHash,
ConsensusHash: h1.ConsensusHash,
AppHash: crypto.CRandBytes(32),
LastResultsHash: h1.LastResultsHash,
EvidenceHash: h1.EvidenceHash,
ProposerAddress: h1.ProposerAddress,
},
Commit: types.NewCommit(h1.Height, 1, h1.Commit.BlockID, h1.Commit.Signatures),
}
h2.Commit.BlockID = types.BlockID{
Hash: h2.Hash(),
PartSetHeader: types.PartSetHeader{Total: 1, Hash: crypto.CRandBytes(32)},
}
vote := &types.Vote{
ValidatorAddress: pv.Key.Address,
ValidatorIndex: 0,
Height: h2.Height,
Round: h2.Commit.Round,
Timestamp: h2.Time,
Type: tmproto.PrecommitType,
BlockID: h2.Commit.BlockID,
}
v := vote.ToProto()
signBytes, err := pv.Key.PrivKey.Sign(types.VoteSignBytes(chainID, v))
require.NoError(t, err)
vote.Signature = v.Signature
h2.Commit.Signatures[0] = types.NewCommitSigForBlock(signBytes, pv.Key.Address, h2.Time)
t.Logf("h1 AppHash: %X", h1.AppHash)
t.Logf("h2 AppHash: %X", h2.AppHash)
ev := &types.ConflictingHeadersEvidence{
H1: &h1.SignedHeader,
H2: h2,
}
result, err := c.BroadcastEvidence(ev)
require.NoError(t, err, "BroadcastEvidence(%s) failed", ev)
assert.Equal(t, ev.Hash(), result.Hash, "expected result hash to match evidence hash")
}
}
func TestBroadcastEmptyEvidence(t *testing.T) {
for _, c := range GetClients() {
_, err := c.BroadcastEvidence(nil)


+ 1
- 6
types/block.go View File

@ -87,12 +87,7 @@ func (b *Block) ValidateBasic() error {
// NOTE: b.Evidence.Evidence may be nil, but we're just looping.
for i, ev := range b.Evidence.Evidence {
switch ev.(type) {
case *ConflictingHeadersEvidence:
// ConflictingHeadersEvidence must be broken up in pieces and never
// committed as a single piece.
return fmt.Errorf("found ConflictingHeadersEvidence (#%d)", i)
case *PotentialAmnesiaEvidence:
if _, ok := ev.(*PotentialAmnesiaEvidence); ok {
// PotentialAmnesiaEvidence does not contribute to anything on its own, so
// reject it as well.
return fmt.Errorf("found PotentialAmnesiaEvidence (#%d)", i)


+ 0
- 3
types/block_test.go View File

@ -86,9 +86,6 @@ func TestBlockValidateBasic(t *testing.T) {
{"Tampered EvidenceHash", func(blk *Block) {
blk.EvidenceHash = []byte("something else")
}, true},
{"ConflictingHeadersEvidence", func(blk *Block) {
blk.Evidence = EvidenceData{Evidence: []Evidence{&ConflictingHeadersEvidence{}}}
}, true},
{"PotentialAmnesiaEvidence", func(blk *Block) {
blk.Evidence = EvidenceData{Evidence: []Evidence{&PotentialAmnesiaEvidence{}}}
}, true},


+ 0
- 306
types/evidence.go View File

@ -12,7 +12,6 @@ import (
"github.com/tendermint/tendermint/crypto/merkle"
"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"
)
@ -31,11 +30,6 @@ type Evidence interface {
String() string
}
type CompositeEvidence interface {
VerifyComposite(committedHeader *Header, valSet *ValidatorSet) error
Split(committedHeader *Header, valSet *ValidatorSet) []Evidence
}
const (
// MaxEvidenceBytes is a maximum size of any evidence (including amino overhead).
MaxEvidenceBytes int64 = 444
@ -98,16 +92,6 @@ func EvidenceToProto(evidence Evidence) (*tmproto.Evidence, error) {
}
return tp, nil
case *ConflictingHeadersEvidence:
pbevi := evi.ToProto()
tp := &tmproto.Evidence{
Sum: &tmproto.Evidence_ConflictingHeadersEvidence{
ConflictingHeadersEvidence: pbevi,
},
}
return tp, nil
case *LunaticValidatorEvidence:
pbevi := evi.ToProto()
@ -153,8 +137,6 @@ func EvidenceFromProto(evidence *tmproto.Evidence) (Evidence, error) {
switch evi := evidence.Sum.(type) {
case *tmproto.Evidence_DuplicateVoteEvidence:
return DuplicateVoteEvidenceFromProto(evi.DuplicateVoteEvidence)
case *tmproto.Evidence_ConflictingHeadersEvidence:
return ConflictingHeadersEvidenceFromProto(evi.ConflictingHeadersEvidence)
case *tmproto.Evidence_LunaticValidatorEvidence:
return LunaticValidatorEvidenceFromProto(evi.LunaticValidatorEvidence)
case *tmproto.Evidence_PotentialAmnesiaEvidence:
@ -168,7 +150,6 @@ func EvidenceFromProto(evidence *tmproto.Evidence) (Evidence, error) {
func init() {
tmjson.RegisterType(&DuplicateVoteEvidence{}, "tendermint/DuplicateVoteEvidence")
tmjson.RegisterType(&ConflictingHeadersEvidence{}, "tendermint/ConflictingHeadersEvidence")
tmjson.RegisterType(&LunaticValidatorEvidence{}, "tendermint/LunaticValidatorEvidence")
tmjson.RegisterType(&PotentialAmnesiaEvidence{}, "tendermint/PotentialAmnesiaEvidence")
tmjson.RegisterType(&AmnesiaEvidence{}, "tendermint/AmnesiaEvidence")
@ -379,286 +360,6 @@ func DuplicateVoteEvidenceFromProto(pb *tmproto.DuplicateVoteEvidence) (*Duplica
return dve, dve.ValidateBasic()
}
// ConflictingHeadersEvidence is primarily used by the light client when it
// observes two conflicting headers, both having 1/3+ of the voting power of
// the currently trusted validator set.
type ConflictingHeadersEvidence struct {
H1 *SignedHeader `json:"h_1"`
H2 *SignedHeader `json:"h_2"`
}
var _ Evidence = &ConflictingHeadersEvidence{}
var _ CompositeEvidence = &ConflictingHeadersEvidence{}
// NewConflictingHeadersEvidence creates a new instance of the respective evidence
func NewConflictingHeadersEvidence(h1, h2 *SignedHeader) *ConflictingHeadersEvidence {
return &ConflictingHeadersEvidence{H1: h1, H2: h2}
}
// Split breaks up evidence into smaller chunks of evidence:
// LunaticValidatorEvidence, DuplicateVoteEvidence and
// PotentialAmnesiaEvidence.
//
// committedHeader - header at height H1.Height == H2.Height
// valSet - validator set at height H1.Height == H2.Height
func (ev *ConflictingHeadersEvidence) Split(committedHeader *Header, valSet *ValidatorSet) []Evidence {
evList := make([]Evidence, 0)
var alternativeHeader *SignedHeader
if bytes.Equal(committedHeader.Hash(), ev.H1.Hash()) {
alternativeHeader = ev.H2
} else {
alternativeHeader = ev.H1
}
// If ValidatorsHash, NextValidatorsHash, ConsensusHash, AppHash, and
// LastResultsHash in alternativeHeader are different (incorrect application
// state transition), then it is a lunatic misbehavior => immediately
// slashable (#F5).
var invalidField string
switch {
case !bytes.Equal(committedHeader.ValidatorsHash, alternativeHeader.ValidatorsHash):
invalidField = "ValidatorsHash"
case !bytes.Equal(committedHeader.NextValidatorsHash, alternativeHeader.NextValidatorsHash):
invalidField = "NextValidatorsHash"
case !bytes.Equal(committedHeader.ConsensusHash, alternativeHeader.ConsensusHash):
invalidField = "ConsensusHash"
case !bytes.Equal(committedHeader.AppHash, alternativeHeader.AppHash):
invalidField = "AppHash"
case !bytes.Equal(committedHeader.LastResultsHash, alternativeHeader.LastResultsHash):
invalidField = "LastResultsHash"
}
if invalidField != "" {
for i, sig := range alternativeHeader.Commit.Signatures {
if sig.Absent() {
continue
}
evList = append(evList, NewLunaticValidatorEvidence(
alternativeHeader.Header,
alternativeHeader.Commit.GetVote(int32(i)),
invalidField,
committedHeader.Time, //take the time of our own trusted header
))
}
return evList
}
// Use the fact that signatures are sorted by ValidatorAddress.
var (
i = 0
j = 0
)
OUTER_LOOP:
for i < len(ev.H1.Commit.Signatures) {
sigA := ev.H1.Commit.Signatures[i]
if sigA.Absent() {
i++
continue
}
// FIXME: Replace with HasAddress once DuplicateVoteEvidence#PubKey is
// removed.
_, val := valSet.GetByAddress(sigA.ValidatorAddress)
if val == nil {
i++
continue
}
for j < len(ev.H2.Commit.Signatures) {
sigB := ev.H2.Commit.Signatures[j]
if sigB.Absent() {
j++
continue
}
switch bytes.Compare(sigA.ValidatorAddress, sigB.ValidatorAddress) {
case 0:
// if H1.Round == H2.Round, and some signers signed different precommit
// messages in both commits, then it is an equivocation misbehavior =>
// immediately slashable (#F1).
if ev.H1.Commit.Round == ev.H2.Commit.Round {
evList = append(evList, NewDuplicateVoteEvidence(
ev.H1.Commit.GetVote(int32(i)),
ev.H2.Commit.GetVote(int32(j)),
ev.H1.Time,
))
} else {
// if H1.Round != H2.Round we need to run full detection procedure => not
// immediately slashable.
firstVote := ev.H1.Commit.GetVote(int32(i))
secondVote := ev.H2.Commit.GetVote(int32(j))
newEv := NewPotentialAmnesiaEvidence(firstVote, secondVote, committedHeader.Time)
// has the validator incorrectly voted for a previous round
if newEv.VoteA.Round > newEv.VoteB.Round {
evList = append(evList, NewAmnesiaEvidence(newEv, NewEmptyPOLC()))
} else {
evList = append(evList, newEv)
}
}
i++
j++
continue OUTER_LOOP
case 1:
i++
continue OUTER_LOOP
case -1:
j++
}
}
}
return evList
}
func (ev *ConflictingHeadersEvidence) Height() int64 { return ev.H1.Height }
// Time returns time of the latest header.
func (ev *ConflictingHeadersEvidence) Time() time.Time {
return maxTime(ev.H1.Time, ev.H2.Time)
}
func (ev *ConflictingHeadersEvidence) Address() []byte {
panic("use ConflictingHeadersEvidence#Split to split evidence into individual pieces")
}
func (ev *ConflictingHeadersEvidence) Bytes() []byte {
pbe := ev.ToProto()
bz, err := pbe.Marshal()
if err != nil {
panic(err)
}
return bz
}
func (ev *ConflictingHeadersEvidence) Hash() []byte {
bz := make([]byte, tmhash.Size*2)
copy(bz[:tmhash.Size-1], ev.H1.Hash().Bytes())
copy(bz[tmhash.Size:], ev.H2.Hash().Bytes())
return tmhash.Sum(bz)
}
func (ev *ConflictingHeadersEvidence) Verify(chainID string, _ crypto.PubKey) error {
panic("use ConflictingHeadersEvidence#VerifyComposite to verify composite evidence")
}
// VerifyComposite verifies that both headers belong to the same chain, same
// height and signed by 1/3+ of validators at height H1.Height == H2.Height.
func (ev *ConflictingHeadersEvidence) VerifyComposite(committedHeader *Header, valSet *ValidatorSet) error {
var alternativeHeader *SignedHeader
switch {
case bytes.Equal(committedHeader.Hash(), ev.H1.Hash()):
alternativeHeader = ev.H2
case bytes.Equal(committedHeader.Hash(), ev.H2.Hash()):
alternativeHeader = ev.H1
default:
return errors.New("none of the headers are committed from this node's perspective")
}
// ChainID must be the same
if committedHeader.ChainID != alternativeHeader.ChainID {
return errors.New("alt header is from a different chain")
}
// Height must be the same
if committedHeader.Height != alternativeHeader.Height {
return errors.New("alt header is from a different height")
}
// Limit the number of signatures to avoid DoS attacks where a header
// contains too many signatures.
//
// Validator set size = 100 [node]
// Max validator set size = 100 * 2 = 200 [fork?]
maxNumValidators := valSet.Size() * 2
if len(alternativeHeader.Commit.Signatures) > maxNumValidators {
return fmt.Errorf("alt commit contains too many signatures: %d, expected no more than %d",
len(alternativeHeader.Commit.Signatures),
maxNumValidators)
}
// Header must be signed by at least 1/3+ of voting power of currently
// trusted validator set.
if err := valSet.VerifyCommitLightTrusting(
alternativeHeader.ChainID,
alternativeHeader.Commit,
tmmath.Fraction{Numerator: 1, Denominator: 3}); err != nil {
return fmt.Errorf("alt header does not have 1/3+ of voting power of our validator set: %w", err)
}
return nil
}
func (ev *ConflictingHeadersEvidence) Equal(ev2 Evidence) bool {
if e2, ok := ev2.(*ConflictingHeadersEvidence); ok {
return bytes.Equal(ev.H1.Hash(), e2.H1.Hash()) && bytes.Equal(ev.H2.Hash(), e2.H2.Hash())
}
return false
}
func (ev *ConflictingHeadersEvidence) ValidateBasic() error {
if ev == nil {
return errors.New("empty conflicting headers evidence")
}
if ev.H1 == nil {
return errors.New("first header is missing")
}
if ev.H2 == nil {
return errors.New("second header is missing")
}
if err := ev.H1.ValidateBasic(ev.H1.ChainID); err != nil {
return fmt.Errorf("h1: %w", err)
}
if err := ev.H2.ValidateBasic(ev.H2.ChainID); err != nil {
return fmt.Errorf("h2: %w", err)
}
return nil
}
func (ev *ConflictingHeadersEvidence) String() string {
return fmt.Sprintf("ConflictingHeadersEvidence{H1: %d#%X, H2: %d#%X}",
ev.H1.Height, ev.H1.Hash(),
ev.H2.Height, ev.H2.Hash())
}
func (ev *ConflictingHeadersEvidence) ToProto() *tmproto.ConflictingHeadersEvidence {
pbh1 := ev.H1.ToProto()
pbh2 := ev.H2.ToProto()
tp := &tmproto.ConflictingHeadersEvidence{
H1: pbh1,
H2: pbh2,
}
return tp
}
func ConflictingHeadersEvidenceFromProto(pb *tmproto.ConflictingHeadersEvidence) (*ConflictingHeadersEvidence, error) {
if pb == nil {
return &ConflictingHeadersEvidence{}, errors.New("nil ConflictingHeadersEvidence")
}
h1, err := SignedHeaderFromProto(pb.H1)
if err != nil {
return &ConflictingHeadersEvidence{}, fmt.Errorf("from proto err: %w", err)
}
h2, err := SignedHeaderFromProto(pb.H2)
if err != nil {
return &ConflictingHeadersEvidence{}, fmt.Errorf("from proto err: %w", err)
}
tp := &ConflictingHeadersEvidence{
H1: h1,
H2: h2,
}
return tp, tp.ValidateBasic()
}
//-------------------------------------------
type LunaticValidatorEvidence struct {
@ -1572,10 +1273,3 @@ func NewMockPOLC(height int64, time time.Time, pubKey crypto.PubKey) ProofOfLock
PubKey: pubKey,
}
}
func maxTime(t1 time.Time, t2 time.Time) time.Time {
if t1.After(t2) {
return t1
}
return t2
}

+ 0
- 110
types/evidence_test.go View File

@ -112,19 +112,12 @@ func TestMaxEvidenceBytes(t *testing.T) {
// InvalidHeaderField: "",
// }
// signedHeader := SignedHeader{Header: makeHeaderRandom(), Commit: randCommit(time.Now())}
// evc := &ConflictingHeadersEvidence{
// H1: &signedHeader,
// H2: &signedHeader,
// }
testCases := []struct {
testName string
evidence Evidence
}{
{"DuplicateVote", ev},
// {"LunaticValidatorEvidence", evl},
// {"ConflictingHeadersEvidence", evc},
}
for _, tt := range testCases {
@ -256,76 +249,6 @@ func TestLunaticValidatorEvidence(t *testing.T) {
}
func TestConflictingHeadersEvidence(t *testing.T) {
const (
chainID = "TestConflictingHeadersEvidence"
height int64 = 37
)
var (
blockID = makeBlockIDRandom()
header1 = makeHeaderRandom()
header2 = makeHeaderRandom()
)
header1.Height = height
header1.LastBlockID = blockID
header1.ChainID = chainID
header2.Height = height
header2.LastBlockID = blockID
header2.ChainID = chainID
voteSet1, valSet, vals := randVoteSet(height, 1, tmproto.PrecommitType, 10, 1)
voteSet2 := NewVoteSet(chainID, height, 1, tmproto.PrecommitType, valSet)
commit1, err := MakeCommit(BlockID{
Hash: header1.Hash(),
PartSetHeader: PartSetHeader{
Total: 100,
Hash: crypto.CRandBytes(tmhash.Size),
},
}, height, 1, voteSet1, vals, time.Now())
require.NoError(t, err)
commit2, err := MakeCommit(BlockID{
Hash: header2.Hash(),
PartSetHeader: PartSetHeader{
Total: 100,
Hash: crypto.CRandBytes(tmhash.Size),
},
}, height, 1, voteSet2, vals, time.Now())
require.NoError(t, err)
h1 := &SignedHeader{
Header: header1,
Commit: commit1,
}
h2 := &SignedHeader{
Header: header2,
Commit: commit2,
}
ev := NewConflictingHeadersEvidence(h1, h2)
assert.Panics(t, func() {
ev.Address()
})
assert.Panics(t, func() {
pubKey, _ := vals[0].GetPubKey()
ev.Verify(chainID, pubKey)
})
assert.Equal(t, height, ev.Height())
assert.Equal(t, ev.H2.Time, ev.Time())
assert.NotEmpty(t, ev.Hash())
assert.NotEmpty(t, ev.Bytes())
assert.NoError(t, ev.VerifyComposite(header1, valSet))
assert.True(t, ev.Equal(ev))
assert.NoError(t, ev.ValidateBasic())
assert.NotEmpty(t, ev.String())
}
func TestPotentialAmnesiaEvidence(t *testing.T) {
const (
chainID = "TestPotentialAmnesiaEvidence"
@ -643,35 +566,6 @@ func TestEvidenceProto(t *testing.T) {
header2.LastBlockID = blockID
header2.ChainID = chainID
voteSet1, valSet, vals := randVoteSet(height, 1, tmproto.PrecommitType, 10, 1)
voteSet2 := NewVoteSet(chainID, height, 1, tmproto.PrecommitType, valSet)
commit1, err := MakeCommit(BlockID{
Hash: header1.Hash(),
PartSetHeader: PartSetHeader{
Total: 100,
Hash: crypto.CRandBytes(tmhash.Size),
},
}, height, 1, voteSet1, vals, time.Now())
require.NoError(t, err)
commit2, err := MakeCommit(BlockID{
Hash: header2.Hash(),
PartSetHeader: PartSetHeader{
Total: 100,
Hash: crypto.CRandBytes(tmhash.Size),
},
}, height, 1, voteSet2, vals, time.Now())
require.NoError(t, err)
h1 := &SignedHeader{
Header: header1,
Commit: commit1,
}
h2 := &SignedHeader{
Header: header2,
Commit: commit2,
}
tests := []struct {
testName string
evidence Evidence
@ -683,10 +577,6 @@ func TestEvidenceProto(t *testing.T) {
{"DuplicateVoteEvidence nil voteB", &DuplicateVoteEvidence{VoteA: v, VoteB: nil}, false, true},
{"DuplicateVoteEvidence nil voteA", &DuplicateVoteEvidence{VoteA: nil, VoteB: v}, false, true},
{"DuplicateVoteEvidence success", &DuplicateVoteEvidence{VoteA: v2, VoteB: v}, false, false},
{"ConflictingHeadersEvidence empty fail", &ConflictingHeadersEvidence{}, false, true},
{"ConflictingHeadersEvidence nil H2", &ConflictingHeadersEvidence{H1: h1, H2: nil}, false, true},
{"ConflictingHeadersEvidence nil H1", &ConflictingHeadersEvidence{H1: nil, H2: h2}, false, true},
{"ConflictingHeadersEvidence success", &ConflictingHeadersEvidence{H1: h1, H2: h2}, false, false},
{"LunaticValidatorEvidence success", &LunaticValidatorEvidence{Header: header1,
Vote: v, InvalidHeaderField: "ValidatorsHash"}, false, true},
{"&LunaticValidatorEvidence empty fail", &LunaticValidatorEvidence{}, false, true},


Loading…
Cancel
Save