Skip to content

Commit

Permalink
Merge branch 'sainoe/ics-misbehaviour-handling' into sainoe/ics-misb-e2e
Browse files Browse the repository at this point in the history
  • Loading branch information
sainoe authored Jul 31, 2023
2 parents 3002fe7 + b00337a commit ec2c60c
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 11 deletions.
14 changes: 11 additions & 3 deletions x/ccv/provider/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,17 @@ $ %s tx provider register-consumer-reward-denom untrn --from mykey

func NewSubmitConsumerMisbehaviourCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "submit-consumer-misbehaviour [misbeaviour]",
Short: "submit a light client misbehaviour for a consumer chain",
Args: cobra.ExactArgs(1),
Use: "submit-consumer-misbehaviour [misbehaviour]",
Short: "submit a IBC misbehaviour for a consumer chain",
Long: strings.TrimSpace(
fmt.Sprintf(`Submit a IBC misbehaviour detected on a consumer chain.
A IBC misbehaviour contains two conflicting IBC client headers, which are used to form a light client attack evidence.
The misbehaviour type definition can be found in the IBC client messages, see ibc-go/proto/ibc/core/client/v1/tx.proto.
Examples:
%s tx provider submit-consumer-misbehaviour [path/to/misbehaviour.json] --from node0 --home ../node0 --chain-id $CID
`, version.AppName)),
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
clientCtx, err := client.GetClientTxContext(cmd)
if err != nil {
Expand Down
22 changes: 14 additions & 8 deletions x/ccv/provider/keeper/misbehaviour.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package keeper

import (
"fmt"
"reflect"
"time"

"github.com/cosmos/interchain-security/v2/x/ccv/provider/types"
Expand All @@ -16,7 +17,7 @@ import (
// CheckConsumerMisbehaviour check that the given IBC misbehaviour headers forms a valid light client attack evidence.
// proceed to the jailing and tombstoning of the bzyantine validators.
func (k Keeper) HandleConsumerMisbehaviour(ctx sdk.Context, misbehaviour ibctmtypes.Misbehaviour) error {
logger := ctx.Logger()
logger := k.Logger(ctx)

if err := k.clientKeeper.CheckMisbehaviourAndUpdateState(ctx, &misbehaviour); err != nil {
logger.Info("Misbehaviour rejected", err.Error())
Expand All @@ -27,7 +28,7 @@ func (k Keeper) HandleConsumerMisbehaviour(ctx sdk.Context, misbehaviour ibctmty
// w.r.t to the last trusted consensus it entails that the infraction age
// isn't too old. see ibc-go/modules/light-clients/07-tendermint/types/misbehaviour_handle.go

// construct a ligth client attack evidence
// construct a light client attack evidence
evidence, err := k.ConstructLightClientEvidence(ctx, misbehaviour)
if err != nil {
return err
Expand Down Expand Up @@ -70,10 +71,10 @@ func (k Keeper) HandleConsumerMisbehaviour(ctx sdk.Context, misbehaviour ibctmty
return nil
}

// ConstructLightClientEvidence constructs and returns a CometBFT Ligth Client Attack(LCA) evidence struct
// ConstructLightClientEvidence constructs and returns a CometBFT Light Client Attack(LCA) evidence struct
// from the given misbehaviour
func (k Keeper) ConstructLightClientEvidence(ctx sdk.Context, misbehaviour ibctmtypes.Misbehaviour) (*tmtypes.LightClientAttackEvidence, error) {
// construct the trusted and conflicetd ligth blocks
// construct the trusted and conflicted light blocks
trusted, err := headerToLightBlock(*misbehaviour.Header1)
if err != nil {
return nil, err
Expand Down Expand Up @@ -113,26 +114,31 @@ func (k Keeper) ConstructLightClientEvidence(ctx sdk.Context, misbehaviour ibctm
// GetCommonFromMisbehaviour checks whether the given ibc misbehaviour's headers share common trusted height
// and that a consensus state exists for this height. In this case, it returns the associated trusted height, timestamp and valset.
func (k Keeper) GetTrustedInfoFromMisbehaviour(ctx sdk.Context, misbehaviour ibctmtypes.Misbehaviour) (int64, time.Time, *tmtypes.ValidatorSet, error) {
// a common trusted height is required
// a common trusted validator set and height is required
commonHeight := misbehaviour.Header1.TrustedHeight
if !commonHeight.EQ(misbehaviour.Header2.TrustedHeight) {
return 0, time.Time{}, nil, fmt.Errorf("misbehaviour headers have different trusted height: %v , %v", commonHeight, misbehaviour.Header2.TrustedHeight)
}

cs, ok := k.clientKeeper.GetClientConsensusState(ctx, misbehaviour.GetClientID(), misbehaviour.Header1.TrustedHeight)
commonValset := misbehaviour.Header1.TrustedValidators
if !reflect.DeepEqual(commonValset.Validators, misbehaviour.Header2.TrustedValidators.Validators) {
return 0, time.Time{}, nil, fmt.Errorf("misbehaviour headers have different trusted validator set: %v , %v", commonHeight, misbehaviour.Header2.TrustedHeight)
}

cs, ok := k.clientKeeper.GetClientConsensusState(ctx, misbehaviour.GetClientID(), commonHeight)
if !ok {
return 0, time.Time{}, nil, fmt.Errorf("cannot find consensus state at trusted height %d for client %s", commonHeight, misbehaviour.GetClientID())
}

vs, err := tmtypes.ValidatorSetFromProto(misbehaviour.Header1.ValidatorSet)
vs, err := tmtypes.ValidatorSetFromProto(commonValset)
if err != nil {
return 0, time.Time{}, nil, err
}

return int64(commonHeight.RevisionHeight), time.Unix(0, int64(cs.GetTimestamp())), vs, nil
}

// headerToLightBlock returns a CometBFT ligth block from the given IBC header
// headerToLightBlock returns a CometBFT light block from the given IBC header
func headerToLightBlock(h ibctmtypes.Header) (*tmtypes.LightBlock, error) {
sh, err := tmtypes.SignedHeaderFromProto(h.SignedHeader)
if err != nil {
Expand Down

0 comments on commit ec2c60c

Please sign in to comment.