github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/ibc-go/modules/core/02-client/keeper/proposal_test.go (about)

     1  package keeper_test
     2  
     3  import (
     4  	govtypes "github.com/fibonacci-chain/fbc/x/gov/types"
     5  
     6  	// govtypes "github.com/cosmos/cosmos-sdk/x/gov/types"
     7  	// upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
     8  	"github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/02-client/types"
     9  	"github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/exported"
    10  	ibctmtypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/light-clients/07-tendermint/types"
    11  	ibctesting "github.com/fibonacci-chain/fbc/libs/ibc-go/testing"
    12  )
    13  
    14  func (suite *KeeperTestSuite) TestClientUpdateProposal() {
    15  	var (
    16  		subject, substitute                       string
    17  		subjectClientState, substituteClientState exported.ClientState
    18  		content                                   govtypes.Content
    19  		err                                       error
    20  	)
    21  
    22  	testCases := []struct {
    23  		name     string
    24  		malleate func()
    25  		expPass  bool
    26  	}{
    27  		{
    28  			"valid update client proposal", func() {
    29  				content = types.NewClientUpdateProposal(ibctesting.Title, ibctesting.Description, subject, substitute)
    30  			}, true,
    31  		},
    32  		{
    33  			"subject and substitute use different revision numbers", func() {
    34  				tmClientState, ok := substituteClientState.(*ibctmtypes.ClientState)
    35  				suite.Require().True(ok)
    36  				consState, found := suite.chainA.App().GetIBCKeeper().ClientKeeper.GetClientConsensusState(suite.chainA.GetContext(), substitute, tmClientState.LatestHeight)
    37  				suite.Require().True(found)
    38  				newRevisionNumber := tmClientState.GetLatestHeight().GetRevisionNumber() + 1
    39  
    40  				tmClientState.LatestHeight = types.NewHeight(newRevisionNumber, tmClientState.GetLatestHeight().GetRevisionHeight())
    41  
    42  				suite.chainA.App().GetIBCKeeper().ClientKeeper.SetClientConsensusState(suite.chainA.GetContext(), substitute, tmClientState.LatestHeight, consState)
    43  				clientStore := suite.chainA.App().GetIBCKeeper().ClientKeeper.ClientStore(suite.chainA.GetContext(), substitute)
    44  				ibctmtypes.SetProcessedTime(clientStore, tmClientState.LatestHeight, 100)
    45  				ibctmtypes.SetProcessedHeight(clientStore, tmClientState.LatestHeight, types.NewHeight(0, 1))
    46  				suite.chainA.App().GetIBCKeeper().ClientKeeper.SetClientState(suite.chainA.GetContext(), substitute, tmClientState)
    47  
    48  				content = types.NewClientUpdateProposal(ibctesting.Title, ibctesting.Description, subject, substitute)
    49  			}, true,
    50  		},
    51  		{
    52  			"cannot use localhost as subject", func() {
    53  				content = types.NewClientUpdateProposal(ibctesting.Title, ibctesting.Description, exported.Localhost, substitute)
    54  			}, false,
    55  		},
    56  		{
    57  			"cannot use localhost as substitute", func() {
    58  				content = types.NewClientUpdateProposal(ibctesting.Title, ibctesting.Description, subject, exported.Localhost)
    59  			}, false,
    60  		},
    61  		{
    62  			"cannot use solomachine as substitute for tendermint client", func() {
    63  				solomachine := ibctesting.NewSolomachine(suite.T(), suite.cdc, "solo machine", "", 1)
    64  				solomachine.Sequence = subjectClientState.GetLatestHeight().GetRevisionHeight() + 1
    65  				substituteClientState = solomachine.ClientState()
    66  				suite.chainA.App().GetIBCKeeper().ClientKeeper.SetClientState(suite.chainA.GetContext(), substitute, substituteClientState)
    67  				content = types.NewClientUpdateProposal(ibctesting.Title, ibctesting.Description, subject, substitute)
    68  			}, false,
    69  		},
    70  		{
    71  			"subject client does not exist", func() {
    72  				content = types.NewClientUpdateProposal(ibctesting.Title, ibctesting.Description, ibctesting.InvalidID, substitute)
    73  			}, false,
    74  		},
    75  		{
    76  			"substitute client does not exist", func() {
    77  				content = types.NewClientUpdateProposal(ibctesting.Title, ibctesting.Description, subject, ibctesting.InvalidID)
    78  			}, false,
    79  		},
    80  		{
    81  			"subject and substitute have equal latest height", func() {
    82  				tmClientState, ok := subjectClientState.(*ibctmtypes.ClientState)
    83  				suite.Require().True(ok)
    84  				tmClientState.LatestHeight = substituteClientState.GetLatestHeight().(types.Height)
    85  				suite.chainA.App().GetIBCKeeper().ClientKeeper.SetClientState(suite.chainA.GetContext(), subject, tmClientState)
    86  
    87  				content = types.NewClientUpdateProposal(ibctesting.Title, ibctesting.Description, subject, substitute)
    88  			}, false,
    89  		},
    90  		{
    91  			"update fails, client is not frozen or expired", func() {
    92  				tmClientState, ok := subjectClientState.(*ibctmtypes.ClientState)
    93  				suite.Require().True(ok)
    94  				tmClientState.FrozenHeight = types.ZeroHeight()
    95  				suite.chainA.App().GetIBCKeeper().ClientKeeper.SetClientState(suite.chainA.GetContext(), subject, tmClientState)
    96  
    97  				content = types.NewClientUpdateProposal(ibctesting.Title, ibctesting.Description, subject, substitute)
    98  			}, false,
    99  		},
   100  		{
   101  			"substitute is frozen", func() {
   102  				tmClientState, ok := substituteClientState.(*ibctmtypes.ClientState)
   103  				suite.Require().True(ok)
   104  				tmClientState.FrozenHeight = types.NewHeight(0, 1)
   105  				suite.chainA.App().GetIBCKeeper().ClientKeeper.SetClientState(suite.chainA.GetContext(), substitute, tmClientState)
   106  
   107  				content = types.NewClientUpdateProposal(ibctesting.Title, ibctesting.Description, subject, substitute)
   108  			}, false,
   109  		},
   110  	}
   111  
   112  	for _, tc := range testCases {
   113  		tc := tc
   114  
   115  		suite.Run(tc.name, func() {
   116  			suite.SetupTest() // reset
   117  
   118  			subjectPath := ibctesting.NewPath(suite.chainA, suite.chainB)
   119  			suite.coordinator.SetupClients(subjectPath)
   120  			subject = subjectPath.EndpointA.ClientID
   121  			subjectClientState = suite.chainA.GetClientState(subject)
   122  
   123  			substitutePath := ibctesting.NewPath(suite.chainA, suite.chainB)
   124  			suite.coordinator.SetupClients(substitutePath)
   125  			substitute = substitutePath.EndpointA.ClientID
   126  
   127  			// update substitute twice
   128  			substitutePath.EndpointA.UpdateClient()
   129  			substitutePath.EndpointA.UpdateClient()
   130  			substituteClientState = suite.chainA.GetClientState(substitute)
   131  
   132  			tmClientState, ok := subjectClientState.(*ibctmtypes.ClientState)
   133  			suite.Require().True(ok)
   134  			tmClientState.AllowUpdateAfterMisbehaviour = true
   135  			tmClientState.AllowUpdateAfterExpiry = true
   136  			tmClientState.FrozenHeight = tmClientState.LatestHeight
   137  			suite.chainA.App().GetIBCKeeper().ClientKeeper.SetClientState(suite.chainA.GetContext(), subject, tmClientState)
   138  
   139  			tmClientState, ok = substituteClientState.(*ibctmtypes.ClientState)
   140  			suite.Require().True(ok)
   141  			tmClientState.AllowUpdateAfterMisbehaviour = true
   142  			tmClientState.AllowUpdateAfterExpiry = true
   143  			suite.chainA.App().GetIBCKeeper().ClientKeeper.SetClientState(suite.chainA.GetContext(), substitute, tmClientState)
   144  
   145  			tc.malleate()
   146  
   147  			updateProp, ok := content.(*types.ClientUpdateProposal)
   148  			suite.Require().True(ok)
   149  			err = suite.chainA.App().GetIBCKeeper().ClientKeeper.ClientUpdateProposal(suite.chainA.GetContext(), updateProp)
   150  
   151  			if tc.expPass {
   152  				suite.Require().NoError(err)
   153  			} else {
   154  				suite.Require().Error(err)
   155  			}
   156  		})
   157  	}
   158  
   159  }