From 3ba5a454fa5e0af7eefe8472d5b40723bc03db49 Mon Sep 17 00:00:00 2001 From: Charly Date: Mon, 21 Nov 2022 16:27:14 +0100 Subject: [PATCH 1/3] mv fn --- .../06-solomachine/misbehaviour_handle.go | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/modules/light-clients/06-solomachine/misbehaviour_handle.go b/modules/light-clients/06-solomachine/misbehaviour_handle.go index f89eae81c6c..26d8d0f5442 100644 --- a/modules/light-clients/06-solomachine/misbehaviour_handle.go +++ b/modules/light-clients/06-solomachine/misbehaviour_handle.go @@ -9,6 +9,22 @@ import ( commitmenttypes "github.com/cosmos/ibc-go/v6/modules/core/23-commitment/types" ) +func (cs ClientState) verifyMisbehaviour(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, misbehaviour *Misbehaviour) error { + // NOTE: a check that the misbehaviour message data are not equal is done by + // misbehaviour.ValidateBasic which is called by the 02-client keeper. + // verify first signature + if err := cs.verifySignatureAndData(cdc, misbehaviour, misbehaviour.SignatureOne); err != nil { + return sdkerrors.Wrap(err, "failed to verify signature one") + } + + // verify second signature + if err := cs.verifySignatureAndData(cdc, misbehaviour, misbehaviour.SignatureTwo); err != nil { + return sdkerrors.Wrap(err, "failed to verify signature two") + } + + return nil +} + // verifySignatureAndData verifies that the currently registered public key has signed // over the provided data and that the data is valid. The data is valid if it can be // unmarshaled into the specified data type. @@ -47,19 +63,3 @@ func (cs ClientState) verifySignatureAndData(cdc codec.BinaryCodec, misbehaviour return nil } - -func (cs ClientState) verifyMisbehaviour(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, misbehaviour *Misbehaviour) error { - // NOTE: a check that the misbehaviour message data are not equal is done by - // misbehaviour.ValidateBasic which is called by the 02-client keeper. - // verify first signature - if err := cs.verifySignatureAndData(cdc, misbehaviour, misbehaviour.SignatureOne); err != nil { - return sdkerrors.Wrap(err, "failed to verify signature one") - } - - // verify second signature - if err := cs.verifySignatureAndData(cdc, misbehaviour, misbehaviour.SignatureTwo); err != nil { - return sdkerrors.Wrap(err, "failed to verify signature two") - } - - return nil -} From a7ab28dcb41ae9c4d229c12ec2ebbed105f5c25a Mon Sep 17 00:00:00 2001 From: Charly Date: Mon, 21 Nov 2022 16:33:07 +0100 Subject: [PATCH 2/3] mv fn --- .../06-solomachine/misbehaviour_handle.go | 10 ++++++++++ modules/light-clients/06-solomachine/update.go | 9 --------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/modules/light-clients/06-solomachine/misbehaviour_handle.go b/modules/light-clients/06-solomachine/misbehaviour_handle.go index 26d8d0f5442..e13e23ae46e 100644 --- a/modules/light-clients/06-solomachine/misbehaviour_handle.go +++ b/modules/light-clients/06-solomachine/misbehaviour_handle.go @@ -7,8 +7,18 @@ import ( sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" commitmenttypes "github.com/cosmos/ibc-go/v6/modules/core/23-commitment/types" + "github.com/cosmos/ibc-go/v6/modules/core/exported" ) +// CheckForMisbehaviour returns true for type Misbehaviour (passed VerifyClientMessage check), otherwise returns false +func (cs ClientState) CheckForMisbehaviour(_ sdk.Context, _ codec.BinaryCodec, _ sdk.KVStore, clientMsg exported.ClientMessage) bool { + if _, ok := clientMsg.(*Misbehaviour); ok { + return true + } + + return false +} + func (cs ClientState) verifyMisbehaviour(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, misbehaviour *Misbehaviour) error { // NOTE: a check that the misbehaviour message data are not equal is done by // misbehaviour.ValidateBasic which is called by the 02-client keeper. diff --git a/modules/light-clients/06-solomachine/update.go b/modules/light-clients/06-solomachine/update.go index ae32cc95cae..2ccd4d74add 100644 --- a/modules/light-clients/06-solomachine/update.go +++ b/modules/light-clients/06-solomachine/update.go @@ -106,15 +106,6 @@ func (cs ClientState) UpdateState(ctx sdk.Context, cdc codec.BinaryCodec, client return []exported.Height{clienttypes.NewHeight(0, cs.Sequence)} } -// CheckForMisbehaviour returns true for type Misbehaviour (passed VerifyClientMessage check), otherwise returns false -func (cs ClientState) CheckForMisbehaviour(_ sdk.Context, _ codec.BinaryCodec, _ sdk.KVStore, clientMsg exported.ClientMessage) bool { - if _, ok := clientMsg.(*Misbehaviour); ok { - return true - } - - return false -} - // UpdateStateOnMisbehaviour updates state upon misbehaviour. This method should only be called on misbehaviour // as it does not perform any misbehaviour checks. func (cs ClientState) UpdateStateOnMisbehaviour(ctx sdk.Context, cdc codec.BinaryCodec, clientStore sdk.KVStore, _ exported.ClientMessage) { From ba718cef6be93c62d4c563b9fe47b59d5d4c2128 Mon Sep 17 00:00:00 2001 From: Charly Date: Mon, 21 Nov 2022 16:36:28 +0100 Subject: [PATCH 3/3] mv fn --- .../07-tendermint/misbehaviour_handle.go | 47 +++++++++++++++++++ modules/light-clients/07-tendermint/update.go | 46 ------------------ 2 files changed, 47 insertions(+), 46 deletions(-) diff --git a/modules/light-clients/07-tendermint/misbehaviour_handle.go b/modules/light-clients/07-tendermint/misbehaviour_handle.go index b5d6059a946..5b970de4584 100644 --- a/modules/light-clients/07-tendermint/misbehaviour_handle.go +++ b/modules/light-clients/07-tendermint/misbehaviour_handle.go @@ -2,6 +2,7 @@ package tendermint import ( "bytes" + "reflect" "time" "github.com/cosmos/cosmos-sdk/codec" @@ -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. // diff --git a/modules/light-clients/07-tendermint/update.go b/modules/light-clients/07-tendermint/update.go index 209b5b53a62..ecd1f58e21e 100644 --- a/modules/light-clients/07-tendermint/update.go +++ b/modules/light-clients/07-tendermint/update.go @@ -3,7 +3,6 @@ package tendermint import ( "bytes" "fmt" - "reflect" "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" @@ -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) {