Skip to content

Commit

Permalink
chore: move Tendermint CheckForMisbehaviour to `misbehaviour_handle.g…
Browse files Browse the repository at this point in the history
…o` (cosmos#2803)
  • Loading branch information
charleenfei authored Nov 22, 2022
1 parent 3f27d4e commit 7d60efa
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 46 deletions.
47 changes: 47 additions & 0 deletions modules/light-clients/07-tendermint/misbehaviour_handle.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package tendermint

import (
"bytes"
"reflect"
"time"

"github.com/cosmos/cosmos-sdk/codec"
Expand All @@ -10,8 +11,54 @@ import (
tmtypes "github.com/tendermint/tendermint/types"

clienttypes "github.com/cosmos/ibc-go/v6/modules/core/02-client/types"
"github.com/cosmos/ibc-go/v6/modules/core/exported"
)

// CheckForMisbehaviour detects duplicate height misbehaviour and BFT time violation misbehaviour
func (cs ClientState) CheckForMisbehaviour(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, msg exported.ClientMessage) bool {
switch msg := msg.(type) {
case *Header:
tmHeader := msg
consState := tmHeader.ConsensusState()

// Check if the Client store already has a consensus state for the header's height
// If the consensus state exists, and it matches the header then we return early
// since header has already been submitted in a previous UpdateClient.
existingConsState, _ := GetConsensusState(clientStore, cdc, tmHeader.GetHeight())
if existingConsState != nil {
// This header has already been submitted and the necessary state is already stored
// in client store, thus we can return early without further validation.
if reflect.DeepEqual(existingConsState, tmHeader.ConsensusState()) { //nolint:gosimple
return false
}

// A consensus state already exists for this height, but it does not match the provided header.
// The assumption is that Header has already been validated. Thus we can return true as misbehaviour is present
return true
}

// Check that consensus state timestamps are monotonic
prevCons, prevOk := GetPreviousConsensusState(clientStore, cdc, tmHeader.GetHeight())
nextCons, nextOk := GetNextConsensusState(clientStore, cdc, tmHeader.GetHeight())
// if previous consensus state exists, check consensus state time is greater than previous consensus state time
// if previous consensus state is not before current consensus state return true
if prevOk && !prevCons.Timestamp.Before(consState.Timestamp) {
return true
}
// if next consensus state exists, check consensus state time is less than next consensus state time
// if next consensus state is not after current consensus state return true
if nextOk && !nextCons.Timestamp.After(consState.Timestamp) {
return true
}
case *Misbehaviour:
// The correctness of Misbehaviour ClientMessage types is ensured by calling VerifyClientMessage prior to this function
// Thus, here we can return true, as ClientMessage is of type Misbehaviour
return true
}

return false
}

// verifyMisbehaviour determines whether or not two conflicting
// headers at the same height would have convinced the light client.
//
Expand Down
46 changes: 0 additions & 46 deletions modules/light-clients/07-tendermint/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package tendermint
import (
"bytes"
"fmt"
"reflect"

"github.com/cosmos/cosmos-sdk/codec"
sdk "github.com/cosmos/cosmos-sdk/types"
Expand Down Expand Up @@ -195,51 +194,6 @@ func (cs ClientState) pruneOldestConsensusState(ctx sdk.Context, cdc codec.Binar
}
}

// CheckForMisbehaviour detects duplicate height misbehaviour and BFT time violation misbehaviour
func (cs ClientState) CheckForMisbehaviour(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, msg exported.ClientMessage) bool {
switch msg := msg.(type) {
case *Header:
tmHeader := msg
consState := tmHeader.ConsensusState()

// Check if the Client store already has a consensus state for the header's height
// If the consensus state exists, and it matches the header then we return early
// since header has already been submitted in a previous UpdateClient.
existingConsState, _ := GetConsensusState(clientStore, cdc, tmHeader.GetHeight())
if existingConsState != nil {
// This header has already been submitted and the necessary state is already stored
// in client store, thus we can return early without further validation.
if reflect.DeepEqual(existingConsState, tmHeader.ConsensusState()) { //nolint:gosimple
return false
}

// A consensus state already exists for this height, but it does not match the provided header.
// The assumption is that Header has already been validated. Thus we can return true as misbehaviour is present
return true
}

// Check that consensus state timestamps are monotonic
prevCons, prevOk := GetPreviousConsensusState(clientStore, cdc, tmHeader.GetHeight())
nextCons, nextOk := GetNextConsensusState(clientStore, cdc, tmHeader.GetHeight())
// if previous consensus state exists, check consensus state time is greater than previous consensus state time
// if previous consensus state is not before current consensus state return true
if prevOk && !prevCons.Timestamp.Before(consState.Timestamp) {
return true
}
// if next consensus state exists, check consensus state time is less than next consensus state time
// if next consensus state is not after current consensus state return true
if nextOk && !nextCons.Timestamp.After(consState.Timestamp) {
return true
}
case *Misbehaviour:
// The correctness of Misbehaviour ClientMessage types is ensured by calling VerifyClientMessage prior to this function
// Thus, here we can return true, as ClientMessage is of type Misbehaviour
return true
}

return false
}

// UpdateStateOnMisbehaviour updates state upon misbehaviour, freezing the ClientState. This method should only be called when misbehaviour is detected
// as it does not perform any misbehaviour checks.
func (cs ClientState) UpdateStateOnMisbehaviour(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, _ exported.ClientMessage) {
Expand Down

0 comments on commit 7d60efa

Please sign in to comment.