Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: check client status active when verifying membership on tenderm… #5865

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions modules/core/errors/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Up @@ -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,
Expand Down
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
Expand Up @@ -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 {
Expand Down
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
Expand Up @@ -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)
Expand Down
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
Expand Up @@ -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 {
Expand Down