Skip to content

Commit

Permalink
Misbehaviour Monitoring (cosmos#457)
Browse files Browse the repository at this point in the history
* Handle misbehaviour on update client event

* Address few PR comments

* Apply @colin-axner suggestions

* Address new  PR comments

* Address @fedekunze review comments
  • Loading branch information
akhilkumarpilli committed Mar 22, 2021
1 parent 1ff4ae1 commit 87cef08
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
VERSION := $(shell echo $(shell git describe --tags) | sed 's/^v//')
COMMIT := $(shell git log -1 --format='%H')
SDKCOMMIT := $(shell go list -m -u -f '{{.Version}}' github.com/cosmos/cosmos-sdk)
GAIA_VERSION := v4.0.0
GAIA_VERSION := v4.1.0
AKASH_VERSION := jack/update-sdk
WASMD_VERSION := v0.14.1

Expand Down
87 changes: 87 additions & 0 deletions relayer/misbehaviour.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package relayer

import (
"encoding/hex"
"fmt"

sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
clienttypes "github.com/cosmos/cosmos-sdk/x/ibc/core/02-client/types"
tmclient "github.com/cosmos/cosmos-sdk/x/ibc/light-clients/07-tendermint/types"
)

var (
// strings for parsing events
updateCliTag = "update_client"
headerTag = "header"
clientIDTag = "client_id"
)

// checkAndSubmitMisbehaviour check headers from update_client tx events
// against the associated light client. If the headers do not match, the emitted
// header and a reconstructed header are used in misbehaviour submission to
// the IBC client on the source chain.
func checkAndSubmitMisbehaviour(src *Chain, events map[string][]string) error {
hdrs, ok := events[fmt.Sprintf("%s.%s", updateCliTag, headerTag)]
if !ok {
return nil
}
for i, hdr := range hdrs {
clientIDs := events[fmt.Sprintf("%s.%s", updateCliTag, clientIDTag)]
if len(clientIDs) <= i {
return fmt.Errorf("emitted client-ids count is less than emitted headers count")
}

emittedClientID := clientIDs[i]
if src.PathEnd.ClientID != emittedClientID {
continue
}

hdrBytes, err := hex.DecodeString(hdr)
if err != nil {
return sdkerrors.Wrapf(err, "failed decoding hexadecimal string of header with client-id: %s",
emittedClientID)
}

exportedHeader, err := clienttypes.UnmarshalHeader(src.Encoding.Marshaler, hdrBytes)
if err != nil {
return sdkerrors.Wrapf(err, "failed unmarshaling header with client-id: %s", emittedClientID)
}

emittedHeader, ok := exportedHeader.(*tmclient.Header)
if !ok {
return fmt.Errorf("emitted header is not tendermint type")
}

trustedHeader, err := src.GetLightSignedHeaderAtHeight(emittedHeader.Header.Height)
if err != nil {
return err
}

if IsMatchingConsensusState(emittedHeader.ConsensusState(), trustedHeader.ConsensusState()) {
continue
}

trustedHeader.TrustedValidators = emittedHeader.TrustedValidators
trustedHeader.TrustedHeight = emittedHeader.TrustedHeight

misbehaviour := tmclient.NewMisbehaviour(emittedClientID, emittedHeader, trustedHeader)
msg, err := clienttypes.NewMsgSubmitMisbehaviour(emittedClientID, misbehaviour, src.MustGetAddress())
if err != nil {
return err
}
if err := msg.ValidateBasic(); err != nil {
return err
}
res, success, err := src.SendMsg(msg)
if err != nil {
return err
}
if !success {
return fmt.Errorf("submit misbehaviour tx failed: %s", res.RawLog)
}
src.Log(fmt.Sprintf("Submitted misbehaviour for emitted header with height: %d",
emittedHeader.Header.Height))
}

return nil
}
6 changes: 6 additions & 0 deletions relayer/naive-strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,12 @@ func (nrs *NaiveStrategy) UnrelayedAcknowledgements(src, dst *Chain) (*RelaySequ

// HandleEvents defines how the relayer will handle block and transaction events as they are emitted
func (nrs *NaiveStrategy) HandleEvents(src, dst *Chain, events map[string][]string) {
// check for misbehaviour and submit if found
err := checkAndSubmitMisbehaviour(src, events)
if err != nil {
src.Error(err)
}

rlyPackets, err := relayPacketsFromEventListener(src.PathEnd, dst.PathEnd, events)
if len(rlyPackets) > 0 && err == nil {
nrs.sendTxFromEventPackets(src, dst, rlyPackets)
Expand Down

0 comments on commit 87cef08

Please sign in to comment.