package types import ( "fmt" "time" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto/tmhash" tmbytes "github.com/tendermint/tendermint/libs/bytes" "gopkg.in/yaml.v2" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/evidence/exported" ) // Evidence type constants const ( RouteEquivocation = "equivocation" TypeEquivocation = "equivocation" ) var _ exported.Evidence = &Equivocation{} // Route returns the Evidence Handler route for an Equivocation type. func (e *Equivocation) Route() string { return RouteEquivocation } // Type returns the Evidence Handler type for an Equivocation type. func (e *Equivocation) Type() string { return TypeEquivocation } func (e *Equivocation) String() string { bz, _ := yaml.Marshal(e) return string(bz) } // Hash returns the hash of an Equivocation object. func (e *Equivocation) Hash() tmbytes.HexBytes { bz, err := e.Marshal() if err != nil { panic(err) } return tmhash.Sum(bz) } // ValidateBasic performs basic stateless validation checks on an Equivocation object. func (e *Equivocation) ValidateBasic() error { if e.Time.IsZero() { return fmt.Errorf("invalid equivocation time: %s", e.Time) } if e.Height < 1 { return fmt.Errorf("invalid equivocation height: %d", e.Height) } if e.Power < 1 { return fmt.Errorf("invalid equivocation validator power: %d", e.Power) } if e.ConsensusAddress == "" { return fmt.Errorf("invalid equivocation validator consensus address: %s", e.ConsensusAddress) } return nil } // GetConsensusAddress returns the validator's consensus address at time of the // Equivocation infraction. func (e Equivocation) GetConsensusAddress() sdk.ConsAddress { addr, _ := sdk.ConsAddressFromBech32(e.ConsensusAddress) return addr } // GetHeight returns the height at time of the Equivocation infraction. func (e Equivocation) GetHeight() int64 { return e.Height } // GetTime returns the time at time of the Equivocation infraction. func (e Equivocation) GetTime() time.Time { return e.Time } // GetValidatorPower returns the validator's power at time of the Equivocation // infraction. func (e Equivocation) GetValidatorPower() int64 { return e.Power } // GetTotalPower is a no-op for the Equivocation type. func (e Equivocation) GetTotalPower() int64 { return 0 } // FromABCIEvidence converts a Tendermint concrete Evidence type to // SDK Evidence using Equivocation as the concrete type. func FromABCIEvidence(e abci.Evidence) exported.Evidence { consAddr, err := sdk.Bech32ifyAddressBytes(sdk.Bech32PrefixConsAddr, e.Validator.Address) if err != nil { panic(err) } return &Equivocation{ Height: e.Height, Power: e.Validator.Power, ConsensusAddress: consAddr, Time: e.Time, } }