func (l *LightClientAttackEvidence) GenerateABCI(
	commonVals *ValidatorSet,
	trustedHeader *SignedHeader,
	evidenceTime time.Time,
) {
	l.Timestamp = evidenceTime
	l.TotalVotingPower = commonVals.TotalVotingPower()
	l.ByzantineValidators = l.GetByzantineValidators(commonVals, trustedHeader)
}
GenerateABCI populates the ABCI component of the evidence: the timestamp,
total voting power and byantine validators
package types
import (
	"bytes"
	"context"
	"encoding/binary"
	"errors"
	"fmt"
	"sort"
	"strings"
	"time"
	abci "github.com/tendermint/tendermint/abci/types"
	"github.com/tendermint/tendermint/crypto/merkle"
	"github.com/tendermint/tendermint/crypto/tmhash"
	tmjson "github.com/tendermint/tendermint/libs/json"
	tmrand "github.com/tendermint/tendermint/libs/rand"
	tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
)
type Evidence interface {
	ABCI() []abci.Evidence  
	Bytes() []byte          
	Hash() []byte           
	Height() int64          
	String() string         
	Time() time.Time        
	ValidateBasic() error   
}
type DuplicateVoteEvidence struct {
	VoteA *Vote `json:"vote_a"`
	VoteB *Vote `json:"vote_b"`
	TotalVotingPower int64
	ValidatorPower   int64
	Timestamp        time.Time
}
var _ Evidence = &DuplicateVoteEvidence{}
func NewDuplicateVoteEvidence(vote1, vote2 *Vote, blockTime time.Time, valSet *ValidatorSet,
) (*DuplicateVoteEvidence, error) {
	var voteA, voteB *Vote
	if vote1 == nil || vote2 == nil {
		return nil, errors.New("missing vote")
	}
	if valSet == nil {
		return nil, errors.New("missing validator set")
	}
	idx, val := valSet.GetByAddress(vote1.ValidatorAddress)
	if idx == -1 {
		return nil, errors.New("validator not in validator set")
	}
	if strings.Compare(vote1.BlockID.Key(), vote2.BlockID.Key()) == -1 {
		voteA = vote1
		voteB = vote2
	} else {
		voteA = vote2
		voteB = vote1
	}
	return &DuplicateVoteEvidence{
		VoteA:            voteA,
		VoteB:            voteB,
		TotalVotingPower: valSet.TotalVotingPower(),
		ValidatorPower:   val.VotingPower,
		Timestamp:        blockTime,
	}, nil
}
func (dve *DuplicateVoteEvidence) ABCI() []abci.Evidence {
	return []abci.Evidence{{
		Type: abci.EvidenceType_DUPLICATE_VOTE,
		Validator: abci.Validator{
			Address: dve.VoteA.ValidatorAddress,
			Power:   dve.ValidatorPower,
		},
		Height:           dve.VoteA.Height,
		Time:             dve.Timestamp,
		TotalVotingPower: dve.TotalVotingPower,
	}}
}
func (dve *DuplicateVoteEvidence) Bytes() []byte {
	pbe := dve.ToProto()
	bz, err := pbe.Marshal()
	if err != nil {
		panic("marshaling duplicate vote evidence to bytes: " + err.Error())
	}
	return bz
}
func (dve *DuplicateVoteEvidence) Hash() []byte {
	return tmhash.Sum(dve.Bytes())
}
func (dve *DuplicateVoteEvidence) Height() int64 {
	return dve.VoteA.Height
}
func (dve *DuplicateVoteEvidence) String() string {
	return fmt.Sprintf("DuplicateVoteEvidence{VoteA: %v, VoteB: %v}", dve.VoteA, dve.VoteB)
}
func (dve *DuplicateVoteEvidence) Time() time.Time {
	return dve.Timestamp
}
func (dve *DuplicateVoteEvidence) ValidateBasic() error {
	if dve == nil {
		return errors.New("empty duplicate vote evidence")
	}
	if dve.VoteA == nil || dve.VoteB == nil {
		return fmt.Errorf("one or both of the votes are empty %v, %v", dve.VoteA, dve.VoteB)
	}
	if err := dve.VoteA.ValidateBasic(); err != nil {
		return fmt.Errorf("invalid VoteA: %w", err)
	}
	if err := dve.VoteB.ValidateBasic(); err != nil {
		return fmt.Errorf("invalid VoteB: %w", err)
	}
	if strings.Compare(dve.VoteA.BlockID.Key(), dve.VoteB.BlockID.Key()) >= 0 {
		return errors.New("duplicate votes in invalid order")
	}
	return nil
}
func (dve *DuplicateVoteEvidence) ValidateABCI(
	val *Validator,
	valSet *ValidatorSet,
	evidenceTime time.Time,
) error {
	if dve.Timestamp != evidenceTime {
		return fmt.Errorf(
			"evidence has a different time to the block it is associated with (%v != %v)",
			dve.Timestamp, evidenceTime)
	}
	if val.VotingPower != dve.ValidatorPower {
		return fmt.Errorf("validator power from evidence and our validator set does not match (%d != %d)",
			dve.ValidatorPower, val.VotingPower)
	}
	if valSet.TotalVotingPower() != dve.TotalVotingPower {
		return fmt.Errorf("total voting power from the evidence and our validator set does not match (%d != %d)",
			dve.TotalVotingPower, valSet.TotalVotingPower())
	}
	return nil
}
func (dve *DuplicateVoteEvidence) GenerateABCI(
	val *Validator,
	valSet *ValidatorSet,
	evidenceTime time.Time,
) {
	dve.ValidatorPower = val.VotingPower
	dve.TotalVotingPower = valSet.TotalVotingPower()
	dve.Timestamp = evidenceTime
}
func (dve *DuplicateVoteEvidence) ToProto() *tmproto.DuplicateVoteEvidence {
	voteB := dve.VoteB.ToProto()
	voteA := dve.VoteA.ToProto()
	tp := tmproto.DuplicateVoteEvidence{
		VoteA:            voteA,
		VoteB:            voteB,
		TotalVotingPower: dve.TotalVotingPower,
		ValidatorPower:   dve.ValidatorPower,
		Timestamp:        dve.Timestamp,
	}
	return &tp
}
func DuplicateVoteEvidenceFromProto(pb *tmproto.DuplicateVoteEvidence) (*DuplicateVoteEvidence, error) {
	if pb == nil {
		return nil, errors.New("nil duplicate vote evidence")
	}
	vA, err := VoteFromProto(pb.VoteA)
	if err != nil {
		return nil, err
	}
	vB, err := VoteFromProto(pb.VoteB)
	if err != nil {
		return nil, err
	}
	dve := &DuplicateVoteEvidence{
		VoteA:            vA,
		VoteB:            vB,
		TotalVotingPower: pb.TotalVotingPower,
		ValidatorPower:   pb.ValidatorPower,
		Timestamp:        pb.Timestamp,
	}
	return dve, dve.ValidateBasic()
}
type LightClientAttackEvidence struct {
	ConflictingBlock *LightBlock
	CommonHeight     int64
	ByzantineValidators []*Validator  
	TotalVotingPower    int64         
	Timestamp           time.Time     
}
var _ Evidence = &LightClientAttackEvidence{}
func (l *LightClientAttackEvidence) ABCI() []abci.Evidence {
	abciEv := make([]abci.Evidence, len(l.ByzantineValidators))
	for idx, val := range l.ByzantineValidators {
		abciEv[idx] = abci.Evidence{
			Type:             abci.EvidenceType_LIGHT_CLIENT_ATTACK,
			Validator:        TM2PB.Validator(val),
			Height:           l.Height(),
			Time:             l.Timestamp,
			TotalVotingPower: l.TotalVotingPower,
		}
	}
	return abciEv
}
func (l *LightClientAttackEvidence) Bytes() []byte {
	pbe, err := l.ToProto()
	if err != nil {
		panic("converting light client attack evidence to proto: " + err.Error())
	}
	bz, err := pbe.Marshal()
	if err != nil {
		panic("marshaling light client attack evidence to bytes: " + err.Error())
	}
	return bz
}
func (l *LightClientAttackEvidence) GetByzantineValidators(commonVals *ValidatorSet,
	trusted *SignedHeader) []*Validator {
	var validators []*Validator
	if l.ConflictingHeaderIsInvalid(trusted.Header) {
		for _, commitSig := range l.ConflictingBlock.Commit.Signatures {
			if !commitSig.ForBlock() {
				continue
			}
			_, val := commonVals.GetByAddress(commitSig.ValidatorAddress)
			if val == nil {
				continue
			}
			validators = append(validators, val)
		}
		sort.Sort(ValidatorsByVotingPower(validators))
		return validators
	} else if trusted.Commit.Round == l.ConflictingBlock.Commit.Round {
		for i := 0; i < len(l.ConflictingBlock.Commit.Signatures); i++ {
			sigA := l.ConflictingBlock.Commit.Signatures[i]
			if !sigA.ForBlock() {
				continue
			}
			sigB := trusted.Commit.Signatures[i]
			if !sigB.ForBlock() {
				continue
			}
			_, val := l.ConflictingBlock.ValidatorSet.GetByAddress(sigA.ValidatorAddress)
			validators = append(validators, val)
		}
		sort.Sort(ValidatorsByVotingPower(validators))
		return validators
	}
	return validators
}
func (l *LightClientAttackEvidence) ConflictingHeaderIsInvalid(trustedHeader *Header) bool {
	return !bytes.Equal(trustedHeader.ValidatorsHash, l.ConflictingBlock.ValidatorsHash) ||
		!bytes.Equal(trustedHeader.NextValidatorsHash, l.ConflictingBlock.NextValidatorsHash) ||
		!bytes.Equal(trustedHeader.ConsensusHash, l.ConflictingBlock.ConsensusHash) ||
		!bytes.Equal(trustedHeader.AppHash, l.ConflictingBlock.AppHash) ||
		!bytes.Equal(trustedHeader.LastResultsHash, l.ConflictingBlock.LastResultsHash)
}
func (l *LightClientAttackEvidence) Hash() []byte {
	buf := make([]byte, binary.MaxVarintLen64)
	n := binary.PutVarint(buf, l.CommonHeight)
	bz := make([]byte, tmhash.Size+n)
	copy(bz[:tmhash.Size-1], l.ConflictingBlock.Hash().Bytes())
	copy(bz[tmhash.Size:], buf)
	return tmhash.Sum(bz)
}
func (l *LightClientAttackEvidence) Height() int64 {
	return l.CommonHeight
}
func (l *LightClientAttackEvidence) String() string {
	return fmt.Sprintf(`LightClientAttackEvidence{
		ConflictingBlock: %v, 
		CommonHeight: %d, 
		ByzatineValidators: %v, 
		TotalVotingPower: %d, 
		Timestamp: %v}#%X`,
		l.ConflictingBlock.String(), l.CommonHeight, l.ByzantineValidators,
		l.TotalVotingPower, l.Timestamp, l.Hash())
}
func (l *LightClientAttackEvidence) Time() time.Time {
	return l.Timestamp
}
func (l *LightClientAttackEvidence) ValidateBasic() error {
	if l.ConflictingBlock == nil {
		return errors.New("conflicting block is nil")
	}
	if l.ConflictingBlock.Header == nil {
		return errors.New("conflicting block missing header")
	}
	if l.TotalVotingPower <= 0 {
		return errors.New("negative or zero total voting power")
	}
	if l.CommonHeight <= 0 {
		return errors.New("negative or zero common height")
	}
	if l.CommonHeight > l.ConflictingBlock.Height {
		return fmt.Errorf("common height is ahead of the conflicting block height (%d > %d)",
			l.CommonHeight, l.ConflictingBlock.Height)
	}
	if err := l.ConflictingBlock.ValidateBasic(l.ConflictingBlock.ChainID); err != nil {
		return fmt.Errorf("invalid conflicting light block: %w", err)
	}
	return nil
}
func (l *LightClientAttackEvidence) ValidateABCI(
	commonVals *ValidatorSet,
	trustedHeader *SignedHeader,
	evidenceTime time.Time,
) error {
	if evTotal, valsTotal := l.TotalVotingPower, commonVals.TotalVotingPower(); evTotal != valsTotal {
		return fmt.Errorf("total voting power from the evidence and our validator set does not match (%d != %d)",
			evTotal, valsTotal)
	}
	if l.Timestamp != evidenceTime {
		return fmt.Errorf(
			"evidence has a different time to the block it is associated with (%v != %v)",
			l.Timestamp, evidenceTime)
	}
	validators := l.GetByzantineValidators(commonVals, trustedHeader)
	if validators == nil && l.ByzantineValidators != nil {
		return fmt.Errorf(
			"expected nil validators from an amnesia light client attack but got %d",
			len(l.ByzantineValidators),
		)
	}
	if exp, got := len(validators), len(l.ByzantineValidators); exp != got {
		return fmt.Errorf("expected %d byzantine validators from evidence but got %d", exp, got)
	}
	for idx, val := range validators {
		if !bytes.Equal(l.ByzantineValidators[idx].Address, val.Address) {
			return fmt.Errorf(
				"evidence contained an unexpected byzantine validator address; expected: %v, got: %v",
				val.Address, l.ByzantineValidators[idx].Address,
			)
		}
		if l.ByzantineValidators[idx].VotingPower != val.VotingPower {
			return fmt.Errorf(
				"evidence contained unexpected byzantine validator power; expected %d, got %d",
				val.VotingPower, l.ByzantineValidators[idx].VotingPower,
			)
		}
	}
	return nil
}