Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ICS-2 Implement Misbehavior #5321

Merged
merged 42 commits into from
Dec 5, 2019
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
dbde0d1
ibc client evidence route
fedekunze Nov 12, 2019
4b979b7
Merge branch 'ibc-alpha' of https://github.com/cosmos/cosmos-sdk into…
fedekunze Nov 13, 2019
a7e0588
split evidence from misbehaviour
fedekunze Nov 13, 2019
33ae02e
clean up client events
fedekunze Nov 13, 2019
94790bf
test misbehaviour and evidence
fedekunze Nov 13, 2019
f7db0fe
remove comments
fedekunze Nov 13, 2019
e32f304
remove frozen comments from demo
fedekunze Nov 13, 2019
0c5ee0a
Update x/ibc/02-client/types/tendermint/evidence_test.go
fedekunze Nov 14, 2019
806136a
change evidence to detect malicious chain
AdityaSripal Nov 15, 2019
6c9fe6d
remove unnecessary sort
AdityaSripal Nov 18, 2019
6f7b571
Merge branch 'ibc-alpha' of https://github.com/cosmos/cosmos-sdk into…
fedekunze Nov 20, 2019
d0c8232
Merge branch 'fedekuze/ibc-evidence' of https://github.com/cosmos/cos…
fedekunze Nov 20, 2019
baac2e4
fix evidence and persist committers to check misbehaviour
AdityaSripal Nov 21, 2019
eaac6c5
Merge branch 'ibc-alpha' of https://github.com/cosmos/cosmos-sdk into…
AdityaSripal Nov 21, 2019
948c4c4
minor fixes and remove incorrect tests
AdityaSripal Nov 21, 2019
0d31c59
add evidence tests
AdityaSripal Nov 22, 2019
85ab5e1
remove debug statements
AdityaSripal Nov 22, 2019
74c7d74
Merge branch 'fedekuze/ibc-evidence' of https://github.com/cosmos/cos…
fedekunze Nov 22, 2019
22faf51
cleanup evidence test
AdityaSripal Nov 22, 2019
5a10ee0
start misbehaviour tests
AdityaSripal Nov 23, 2019
3d3c3c7
fix nondeterministic bug
AdityaSripal Nov 25, 2019
373601a
add same height and next height checks in misbehaviour
AdityaSripal Nov 26, 2019
d420a0e
fix bugs
AdityaSripal Nov 26, 2019
4b1aa96
apply fede review suggestions
AdityaSripal Nov 26, 2019
09d834b
finish code review changes
AdityaSripal Nov 26, 2019
3b3cb99
fix GetCommitter and write keeper-level misbehaviour tests
AdityaSripal Nov 27, 2019
4764655
remove incorrect special case checking
AdityaSripal Nov 27, 2019
40cc70f
save
AdityaSripal Dec 3, 2019
51ed94e
final fixes
AdityaSripal Dec 3, 2019
213002d
save
AdityaSripal Dec 3, 2019
68927e4
fix conflict
AdityaSripal Dec 3, 2019
6ae0e28
fix conflict
AdityaSripal Dec 4, 2019
d151f46
fix conflicts and add back submit misbehaviour msg
AdityaSripal Dec 4, 2019
88ac519
Merge branch 'aditya/ibc-evidence' of https://github.com/cosmos/cosmo…
fedekunze Dec 4, 2019
d1386b9
Apply suggestions from code review
AdityaSripal Dec 4, 2019
57c22b4
save
AdityaSripal Dec 4, 2019
7b53102
Merge branch 'aditya/ibc-evidence' of https://github.com/cosmos/cosmo…
AdityaSripal Dec 4, 2019
0202ce4
add godocs and fix test
AdityaSripal Dec 4, 2019
f0d6eac
fix test panics in other modules
AdityaSripal Dec 4, 2019
9858a8f
Update x/ibc/02-client/keeper/client.go
AdityaSripal Dec 4, 2019
a5b42e4
add back aliases
AdityaSripal Dec 4, 2019
a092ff0
Merge branch 'aditya/ibc-evidence' of https://github.com/cosmos/cosmo…
AdityaSripal Dec 4, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions simapp/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/cosmos/cosmos-sdk/x/genutil"
"github.com/cosmos/cosmos-sdk/x/gov"
"github.com/cosmos/cosmos-sdk/x/ibc"
ibcclient "github.com/cosmos/cosmos-sdk/x/ibc/02-client"
ibctransfer "github.com/cosmos/cosmos-sdk/x/ibc/20-transfer"
"github.com/cosmos/cosmos-sdk/x/mint"
"github.com/cosmos/cosmos-sdk/x/params"
Expand Down Expand Up @@ -193,8 +194,9 @@ func NewSimApp(
evidenceKeeper := evidence.NewKeeper(
app.cdc, keys[evidence.StoreKey], app.subspaces[evidence.ModuleName], evidence.DefaultCodespace,
)
evidenceRouter := evidence.NewRouter()
// TODO: Register evidence routes.
evidenceRouter := evidence.NewRouter().
AddRoute(ibcclient.RouterKey, ibcclient.HandlerClientMisbehaviour(app.IBCKeeper.ClientKeeper))

evidenceKeeper.SetRouter(evidenceRouter)
app.EvidenceKeeper = *evidenceKeeper

Expand Down
6 changes: 6 additions & 0 deletions x/evidence/exported/evidence.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ type Evidence interface {
String() string
Hash() cmn.HexBytes
ValidateBasic() error
}

// ValidatorEvidence extends Evidence interface to define contract
// for evidence against malicious validators
type ValidatorEvidence interface {
Evidence

// The consensus address of the malicious validator at time of infraction
GetConsensusAddress() sdk.ConsAddress
Expand Down
11 changes: 4 additions & 7 deletions x/ibc/02-client/alias.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,24 +61,21 @@ var (
KeyRoot = types.KeyRoot
NewMsgCreateClient = types.NewMsgCreateClient
NewMsgUpdateClient = types.NewMsgUpdateClient
NewMsgSubmitMisbehaviour = types.NewMsgSubmitMisbehaviour
NewQueryClientStateParams = types.NewQueryClientStateParams
NewQueryCommitmentRootParams = types.NewQueryCommitmentRootParams
NewClientState = types.NewClientState

// variable aliases
SubModuleCdc = types.SubModuleCdc
EventTypeCreateClient = types.EventTypeCreateClient
EventTypeUpdateClient = types.EventTypeUpdateClient
EventTypeSubmitMisbehaviour = types.EventTypeSubmitMisbehaviour
AttributeValueCategory = types.AttributeValueCategory
SubModuleCdc = types.SubModuleCdc
EventTypeCreateClient = types.EventTypeCreateClient
EventTypeUpdateClient = types.EventTypeUpdateClient
AttributeValueCategory = types.AttributeValueCategory
)

type (
Keeper = keeper.Keeper
MsgCreateClient = types.MsgCreateClient
MsgUpdateClient = types.MsgUpdateClient
MsgSubmitMisbehaviour = types.MsgSubmitMisbehaviour
QueryClientStateParams = types.QueryClientStateParams
QueryCommitmentRootParams = types.QueryCommitmentRootParams
State = types.State
Expand Down
44 changes: 0 additions & 44 deletions x/ibc/02-client/client/cli/tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,47 +126,3 @@ $ %s tx ibc client update [client-id] [path/to/header.json] --from node0 --home
}
return cmd
}

// GetCmdSubmitMisbehaviour defines the command to submit a misbehaviour to invalidate
// previous state roots and prevent future updates as defined in
// https://github.com/cosmos/ics/tree/master/spec/ics-002-client-semantics#misbehaviour
func GetCmdSubmitMisbehaviour(cdc *codec.Codec) *cobra.Command {
cmd := &cobra.Command{
Use: "misbehaviour [client-it] [path/to/evidence.json]",
Short: "submit a client misbehaviour",
Long: strings.TrimSpace(fmt.Sprintf(`submit a client misbehaviour to invalidate to invalidate previous state roots and prevent future updates:

Example:
$ %s tx ibc client misbehaviour [client-id] [path/to/evidence.json] --from node0 --home ../node0/<app>cli --chain-id $CID
`, version.ClientName),
),
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc))
cliCtx := context.NewCLIContext().WithCodec(cdc)

clientID := args[0]

var evidence exported.Evidence
if err := cdc.UnmarshalJSON([]byte(args[1]), &evidence); err != nil {
fmt.Fprintf(os.Stderr, "failed to unmarshall input into struct, checking for file...")

contents, err := ioutil.ReadFile(args[1])
if err != nil {
return fmt.Errorf("error opening proof file: %v", err)
}
if err := cdc.UnmarshalJSON(contents, &evidence); err != nil {
return fmt.Errorf("error unmarshalling evidence file: %v", err)
}
}

msg := types.NewMsgSubmitMisbehaviour(clientID, evidence, cliCtx.GetFromAddress())
if err := msg.ValidateBasic(); err != nil {
return err
}

return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg})
},
}
return cmd
}
29 changes: 2 additions & 27 deletions x/ibc/02-client/exported/exported.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@ import (
"encoding/json"
"fmt"

sdk "github.com/cosmos/cosmos-sdk/types"

cmn "github.com/tendermint/tendermint/libs/common"

evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported"
commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment"
)

Expand All @@ -25,32 +22,10 @@ type ConsensusState interface {
CheckValidityAndUpdateState(Header) (ConsensusState, error)
}

// Evidence from ADR 009: Evidence Module
// TODO: use evidence module interface once merged
type Evidence interface {
Route() string
Type() string
String() string
Hash() cmn.HexBytes
ValidateBasic() sdk.Error

// The consensus address of the malicious validator at time of infraction
GetConsensusAddress() sdk.ConsAddress

// Height at which the infraction occurred
GetHeight() int64

// The total power of the malicious validator at time of infraction
GetValidatorPower() int64

// The total validator set power at time of infraction
GetTotalPower() int64
}

// Misbehaviour defines a specific consensus kind and an evidence
type Misbehaviour interface {
ClientType() ClientType
Evidence() Evidence
GetEvidence() evidenceexported.Evidence
}

// Header is the consensus state update information
Expand Down
39 changes: 18 additions & 21 deletions x/ibc/02-client/handler.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
package client

import (
"fmt"

sdk "github.com/cosmos/cosmos-sdk/types"
exported "github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported"
"github.com/cosmos/cosmos-sdk/x/evidence"
evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported"
"github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported"
"github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint"
)

// HandleMsgCreateClient defines the sdk.Handler for MsgCreateClient
Expand All @@ -12,7 +17,6 @@ func HandleMsgCreateClient(ctx sdk.Context, k Keeper, msg MsgCreateClient) sdk.R
return sdk.ResultFromError(ErrInvalidClientType(DefaultCodespace, err.Error()))
}

// TODO: should we create an event with the new client state id ?
_, err = k.CreateClient(ctx, msg.ClientID, clientType, msg.ConsensusState)
if err != nil {
return sdk.ResultFromError(err)
Expand Down Expand Up @@ -55,24 +59,17 @@ func HandleMsgUpdateClient(ctx sdk.Context, k Keeper, msg MsgUpdateClient) sdk.R
return sdk.Result{Events: ctx.EventManager().Events()}
}

// HandleMsgSubmitMisbehaviour defines the sdk.Handler for MsgSubmitMisbehaviour
func HandleMsgSubmitMisbehaviour(ctx sdk.Context, k Keeper, msg MsgSubmitMisbehaviour) sdk.Result {
err := k.CheckMisbehaviourAndUpdateState(ctx, msg.ClientID, msg.Evidence)
if err != nil {
return sdk.ResultFromError(err)
}
// HandlerClientMisbehaviour defines the Evidence module handler for submitting a
// light client misbehaviour.
func HandlerClientMisbehaviour(k Keeper) evidence.Handler {
return func(ctx sdk.Context, evidence evidenceexported.Evidence) error {
switch e := evidence.(type) {
case tendermint.Misbehaviour:
return k.CheckMisbehaviourAndUpdateState(ctx, evidence)

ctx.EventManager().EmitEvents(sdk.Events{
sdk.NewEvent(
EventTypeSubmitMisbehaviour,
sdk.NewAttribute(AttributeKeyClientID, msg.ClientID),
),
sdk.NewEvent(
sdk.EventTypeMessage,
sdk.NewAttribute(sdk.AttributeKeyModule, AttributeValueCategory),
sdk.NewAttribute(sdk.AttributeKeySender, msg.Signer.String()),
),
})

return sdk.Result{Events: ctx.EventManager().Events()}
default:
errMsg := fmt.Sprintf("unrecognized IBC client evidence type: %T", e)
return sdk.ErrUnknownRequest(errMsg)
}
}
}
33 changes: 25 additions & 8 deletions x/ibc/02-client/keeper/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import (

sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
evidenceexported "github.com/cosmos/cosmos-sdk/x/evidence/exported"
"github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported"
"github.com/cosmos/cosmos-sdk/x/ibc/02-client/types"
"github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors"
"github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint"
)

// CreateClient creates a new client state and populates it with a given consensus
Expand Down Expand Up @@ -73,23 +75,38 @@ func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.H

// CheckMisbehaviourAndUpdateState checks for client misbehaviour and freezes the
// client if so.
func (k Keeper) CheckMisbehaviourAndUpdateState(ctx sdk.Context, clientID string, evidence exported.Evidence) error {
clientState, found := k.GetClientState(ctx, clientID)
//
// NOTE: In the first implementation, only Tendermint misbehaviour evidence is
// supported.
func (k Keeper) CheckMisbehaviourAndUpdateState(ctx sdk.Context, evidence evidenceexported.Evidence) error {
misbehaviour, ok := evidence.(tendermint.Misbehaviour)
if !ok {
return errors.ErrInvalidClientType(k.codespace, "consensus type is not Tendermint")
}

clientState, found := k.GetClientState(ctx, misbehaviour.ClientID)
if !found {
sdk.ResultFromError(errors.ErrClientNotFound(k.codespace, clientID))
sdk.ResultFromError(errors.ErrClientNotFound(k.codespace, misbehaviour.ClientID))
}

err := k.checkMisbehaviour(ctx, evidence)
if err != nil {
return err
if err := tendermint.CheckMisbehaviour(misbehaviour); err != nil {
return errors.ErrInvalidEvidence(k.codespace, err.Error())
}

clientState, err = k.freeze(ctx, clientState)
clientState, err := k.freeze(ctx, clientState)
if err != nil {
return err
}

k.SetClientState(ctx, clientState)
k.Logger(ctx).Info(fmt.Sprintf("client %s frozen due to misbehaviour", clientID))
k.Logger(ctx).Info(fmt.Sprintf("client %s frozen due to misbehaviour", misbehaviour.ClientID))

ctx.EventManager().EmitEvent(
sdk.NewEvent(
types.EventTypeSubmitMisbehaviour,
sdk.NewAttribute(types.AttributeKeyClientID, misbehaviour.ClientID),
),
)

return nil
}
48 changes: 17 additions & 31 deletions x/ibc/02-client/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"github.com/cosmos/cosmos-sdk/x/ibc/02-client/exported"
"github.com/cosmos/cosmos-sdk/x/ibc/02-client/types"
"github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/errors"
"github.com/cosmos/cosmos-sdk/x/ibc/02-client/types/tendermint"
commitment "github.com/cosmos/cosmos-sdk/x/ibc/23-commitment"
ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types"
)
Expand Down Expand Up @@ -127,24 +126,6 @@ func (k Keeper) initialize(ctx sdk.Context, clientID string, consensusState expo
return clientState
}

func (k Keeper) checkMisbehaviour(ctx sdk.Context, evidence exported.Evidence) error {
switch evidence.Type() {
case exported.ClientTypeTendermint:
var tmEvidence tendermint.Evidence
_, ok := evidence.(tendermint.Evidence)
if !ok {
return errors.ErrInvalidClientType(k.codespace, "consensus type is not Tendermint")
}
err := tendermint.CheckMisbehaviour(tmEvidence)
if err != nil {
return errors.ErrInvalidEvidence(k.codespace, err.Error())
}
default:
panic(fmt.Sprintf("unregistered evidence type: %s", evidence.Type()))
}
return nil
}

// freeze updates the state of the client in the event of a misbehaviour
func (k Keeper) freeze(ctx sdk.Context, clientState types.State) (types.State, error) {
if clientState.Frozen {
Expand All @@ -164,12 +145,14 @@ func (k Keeper) VerifyMembership(
path commitment.PathI,
value []byte,
) bool {
// XXX: commented out for demo
/*
if clientState.Frozen {
return false
}
*/
clientState, found := k.GetClientState(ctx, clientID)
if !found {
return false
}

if clientState.Frozen {
return false
}

root, found := k.GetVerifiedRoot(ctx, clientID, height)
if !found {
Expand All @@ -187,12 +170,15 @@ func (k Keeper) VerifyNonMembership(
proof commitment.ProofI,
path commitment.PathI,
) bool {
// XXX: commented out for demo
/*
if clientState.Frozen {
return false
}
*/
clientState, found := k.GetClientState(ctx, clientID)
if !found {
return false
}

if clientState.Frozen {
return false
}

root, found := k.GetVerifiedRoot(ctx, clientID, height)
if !found {
return false
Expand Down
1 change: 0 additions & 1 deletion x/ibc/02-client/types/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ var SubModuleCdc *codec.Codec
// RegisterCodec registers the IBC client interfaces and types
func RegisterCodec(cdc *codec.Codec) {
fedekunze marked this conversation as resolved.
Show resolved Hide resolved
cdc.RegisterInterface((*exported.ConsensusState)(nil), nil)
cdc.RegisterInterface((*exported.Evidence)(nil), nil)
cdc.RegisterInterface((*exported.Header)(nil), nil)
cdc.RegisterInterface((*exported.Misbehaviour)(nil), nil)

Expand Down
6 changes: 3 additions & 3 deletions x/ibc/02-client/types/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ const (

// IBC client events vars
var (
EventTypeCreateClient = MsgCreateClient{}.Type()
EventTypeUpdateClient = MsgUpdateClient{}.Type()
EventTypeSubmitMisbehaviour = MsgSubmitMisbehaviour{}.Type()
EventTypeCreateClient = TypeMsgCreateClient
EventTypeUpdateClient = TypeMsgUpdateClient
EventTypeSubmitMisbehaviour = TypeClientMisbehaviour

AttributeValueCategory = fmt.Sprintf("%s_%s", ibctypes.ModuleName, SubModuleName)
)
8 changes: 4 additions & 4 deletions x/ibc/02-client/types/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ import (

const (
// SubModuleName defines the IBC client name
SubModuleName = "client"
SubModuleName string = "client"

// StoreKey is the store key string for IBC client
StoreKey = SubModuleName
StoreKey string = SubModuleName

// RouterKey is the message route for IBC client
RouterKey = SubModuleName
RouterKey string = SubModuleName

// QuerierRoute is the querier route for IBC client
QuerierRoute = SubModuleName
QuerierRoute string = SubModuleName
)

// KVStore key prefixes
Expand Down
Loading