Skip to content

Commit

Permalink
add doc
Browse files Browse the repository at this point in the history
  • Loading branch information
sainoe committed Nov 2, 2023
1 parent 67cf4b5 commit a71da4e
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 9 deletions.
9 changes: 4 additions & 5 deletions tests/integration/misbehaviour.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ func (s *CCVTestSuite) TestGetByzantineValidators() {
altSigners[clientTMValset.Validators[1].Address.String()] = clientSigners[clientTMValset.Validators[1].Address.String()]
altSigners[clientTMValset.Validators[2].Address.String()] = clientSigners[clientTMValset.Validators[2].Address.String()]

// create a consumer client header
clientHeader := s.consumerChain.CreateTMClientHeader(
s.consumerChain.ChainID,
int64(clientHeight.RevisionHeight+1),
Expand All @@ -105,7 +106,6 @@ func (s *CCVTestSuite) TestGetByzantineValidators() {
clientSigners,
)

// TODO: figure out how to test an amnesia cases for "amnesia" attack
testCases := []struct {
name string
getMisbehaviour func() *ibctmtypes.Misbehaviour
Expand Down Expand Up @@ -160,13 +160,12 @@ func (s *CCVTestSuite) TestGetByzantineValidators() {
true,
},
{
"valid light client attack - equivocation",
"light client attack - equivocation",
func() *ibctmtypes.Misbehaviour {
return &ibctmtypes.Misbehaviour{
ClientId: s.path.EndpointA.ClientID,
Header1: clientHeader,
// the resulting header contains invalid fields
// i.e. ValidatorsHash, NextValidatorsHash etc.
// the resulting header contains a different BlockID
Header2: s.consumerChain.CreateTMClientHeader(
s.consumerChain.ChainID,
int64(clientHeight.RevisionHeight+1),
Expand All @@ -185,7 +184,7 @@ func (s *CCVTestSuite) TestGetByzantineValidators() {
true,
},
{
"valid light client attack - amnesia",
"light client attack - amnesia",
func() *ibctmtypes.Misbehaviour {
// create a valid header with a different hash
// and commit round
Expand Down
20 changes: 16 additions & 4 deletions x/ccv/provider/keeper/misbehaviour.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package keeper

import (
"bytes"
"fmt"

"github.com/cosmos/interchain-security/v2/x/ccv/provider/types"
Expand Down Expand Up @@ -88,11 +89,11 @@ func (k Keeper) GetByzantineValidators(ctx sdk.Context, misbehaviour ibctmtypes.

// Check if the misbehaviour corresponds to an Amnesia attack,
// meaning that the conflicting headers have both valid state transitions
// and different commit rounds. In this case, we return no validators as we can't identify the byzantine validators.
// and different commit rounds. In this case, we return no validators as
// we can't identify the byzantine validators.
//
// Note that we cannot differentiate which of the headers is trusted or malicious.
ev := &tmtypes.LightClientAttackEvidence{ConflictingBlock: lightBlock1}
if !ev.ConflictingHeaderIsInvalid(lightBlock2.Header) && lightBlock1.Commit.Round != lightBlock2.Commit.Round {
// Note that we cannot differentiate which of the headers is trusted or malicious,
if !headersStateTransitionsAreConflicting(*lightBlock1.Header, *lightBlock2.Header) && lightBlock1.Commit.Round != lightBlock2.Commit.Round {
return
}

Expand Down Expand Up @@ -168,3 +169,14 @@ func (k Keeper) CheckMisbehaviour(ctx sdk.Context, misbehaviour ibctmtypes.Misbe

return nil
}

// Check if the given block headers have conflicting state transitions.
// Note that this method was copied from ConflictingHeaderIsInvalid in CometBFT,
// see https://github.com/cometbft/cometbft/blob/v0.34.27/types/evidence.go#L285
func headersStateTransitionsAreConflicting(h1, h2 tmtypes.Header) bool {
return !bytes.Equal(h1.ValidatorsHash, h2.ValidatorsHash) ||
!bytes.Equal(h1.NextValidatorsHash, h2.NextValidatorsHash) ||
!bytes.Equal(h1.ConsensusHash, h2.ConsensusHash) ||
!bytes.Equal(h1.AppHash, h2.AppHash) ||
!bytes.Equal(h1.LastResultsHash, h2.LastResultsHash)
}

0 comments on commit a71da4e

Please sign in to comment.