Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: cosmos/ibc-go
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: main
Choose a base ref
...
head repository: notional-labs/ibc-go
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: feat/check-client-status-on-verify-membership
Choose a head ref
Can’t automatically merge. Don’t worry, you can still create the pull request.
  • 4 commits
  • 5 files changed
  • 1 contributor

Commits on Feb 19, 2024

  1. feat: check client status active when verifying membership on tenderm…

    …int client
    duvbell committed Feb 19, 2024
    Copy the full SHA
    7078f5d View commit details

Commits on Feb 20, 2024

  1. test: verify membership fail when client state is not active

    duvbell committed Feb 20, 2024
    Copy the full SHA
    1c8555a View commit details
  2. Copy the full SHA
    c764db6 View commit details
  3. test: check client state 08-wasm

    duvbell committed Feb 20, 2024
    Copy the full SHA
    7ddcacc View commit details
3 changes: 3 additions & 0 deletions modules/core/errors/errors.go
Original file line number Diff line number Diff line change
@@ -60,4 +60,7 @@ var (

// ErrNotFound defines an error when requested entity doesn't exist in the state.
ErrNotFound = errorsmod.Register(codespace, 16, "not found")

// ErrClientStatusNotActive defines an error when an operation expects a client to be active
ErrClientStatusNotActive = errorsmod.Register(codespace, 17, "client is not active")
)
4 changes: 4 additions & 0 deletions modules/light-clients/07-tendermint/client_state.go
Original file line number Diff line number Diff line change
@@ -219,6 +219,10 @@ func (cs ClientState) VerifyMembership(
path exported.Path,
value []byte,
) error {
if cs.Status(ctx, clientStore, cdc) != exported.Active {
return errorsmod.Wrapf(ibcerrors.ErrClientStatusNotActive, "client status is not active")
}

if cs.GetLatestHeight().LT(height) {
return errorsmod.Wrapf(
ibcerrors.ErrInvalidHeight,
22 changes: 22 additions & 0 deletions modules/light-clients/07-tendermint/client_state_test.go
Original file line number Diff line number Diff line change
@@ -503,6 +503,28 @@ func (suite *TendermintTestSuite) TestVerifyMembership() {
proof = []byte{}
}, false,
},
{
name: "client state is frozen",
malleate: func() {
clientState := testingpath.EndpointA.GetClientState().(*ibctm.ClientState)
// Set the FrozenHeight to a non-zero value to indicate the client is frozen (inactive).
clientState.FrozenHeight = clienttypes.NewHeight(1, 1)
// Update the client state in the testing path to reflect the frozen state.
testingpath.EndpointA.SetClientState(clientState)
},
expPass: false, // Expect this test to fail since the state is not active (frozen).
},
{
name: "client state is expired",
malleate: func() {
clientState := testingpath.EndpointA.GetClientState().(*ibctm.ClientState)
// Advance the LatestHeight to simulate expiration.
clientState.LatestHeight = clientState.LatestHeight.Increment().(clienttypes.Height)
// Update the client state in the testing path to reflect the expired state.
testingpath.EndpointA.SetClientState(clientState)
},
expPass: false, // Expect this test to fail since the client state is expired.
},
}

for _, tc := range testCases {
4 changes: 4 additions & 0 deletions modules/light-clients/08-wasm/types/client_state.go
Original file line number Diff line number Diff line change
@@ -137,6 +137,10 @@ func (cs ClientState) VerifyMembership(
path exported.Path,
value []byte,
) error {
if cs.Status(ctx, clientStore, cdc) != exported.Active {
return errorsmod.Wrapf(ibcerrors.ErrClientStatusNotActive, "client status is not active")
}

proofHeight, ok := height.(clienttypes.Height)
if !ok {
return errorsmod.Wrapf(ibcerrors.ErrInvalidType, "expected %T, got %T", clienttypes.Height{}, height)
26 changes: 26 additions & 0 deletions modules/light-clients/08-wasm/types/client_state_test.go
Original file line number Diff line number Diff line change
@@ -448,6 +448,32 @@ func (suite *TypesTestSuite) TestVerifyMembership() {
},
ibcerrors.ErrInvalidType,
},
{
"client state is frozen",
func() {
// Simulate the client state being frozen by registering a query callback
// that returns a status indicating the client is frozen.
suite.mockVM.RegisterQueryCallback(types.StatusMsg{}, func(checksum wasmvm.Checksum, env wasmvmtypes.Env, queryMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) ([]byte, uint64, error) {
resp, err := json.Marshal(types.StatusResult{Status: exported.Frozen.String()})
suite.Require().NoError(err)
return resp, wasmtesting.DefaultGasUsed, nil
})
},
ibcerrors.ErrClientStatusNotActive, // Adjust based on the expected outcome when the client is frozen.
},
{
"client state is expired",
func() {
// Simulate the client state being expired by registering a query callback
// that returns a status indicating the client is expired.
suite.mockVM.RegisterQueryCallback(types.StatusMsg{}, func(checksum wasmvm.Checksum, env wasmvmtypes.Env, queryMsg []byte, store wasmvm.KVStore, goapi wasmvm.GoAPI, querier wasmvm.Querier, gasMeter wasmvm.GasMeter, gasLimit uint64, deserCost wasmvmtypes.UFraction) ([]byte, uint64, error) {
resp, err := json.Marshal(types.StatusResult{Status: exported.Expired.String()})
suite.Require().NoError(err)
return resp, wasmtesting.DefaultGasUsed, nil
})
},
ibcerrors.ErrClientStatusNotActive, // This needs to be defined according to your error handling for expired clients.
},
}

for _, tc := range testCases {