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: Add GetAllClientIDsOfType query function #2855

Closed
wants to merge 6 commits into from
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ Ref: https://keepachangelog.com/en/1.0.0/

### Features

* (core/02-client) [\#2855](https://github.com/cosmos/ibc-go/pull/2855) Add `GetAllClientIDsOfType` to 02-client keeper.
* (core/24-host) [\#2855](https://github.com/cosmos/ibc-go/pull/2855) Add `PrefixedClientStorePath` and `PrefixedClientStoreKey` functions to 24-host
* (core/02-client) [\#2819](https://github.com/cosmos/ibc-go/pull/2819) Add automatic in-place store migrations to remove the localhost client and migrate existing solo machine definitions.
* (light-clients/06-solomachine) [\#2826](https://github.com/cosmos/ibc-go/pull/2826) Add `AppModuleBasic` for the 06-solomachine client and remove solo machine type registration from core IBC. Chains must register the `AppModuleBasic` of light clients.
* (light-clients/07-tendermint) [\#2825](https://github.com/cosmos/ibc-go/pull/2825) Add `AppModuleBasic` for the 07-tendermint client and remove tendermint type registration from core IBC. Chains must register the `AppModuleBasic` of light clients.
Expand Down
22 changes: 22 additions & 0 deletions modules/core/02-client/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,28 @@ func (k Keeper) GetAllClients(ctx sdk.Context) (states []exported.ClientState) {
return states
}

// GetAllClientIDsOfType will iterate over the provided client type prefix in the client store
// and return a list of clientIDs associated with the client type.
func (k Keeper) GetAllClientIDsOfType(ctx sdk.Context, clientType string) (clientIDs []string) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be used in a followup pr

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a preference for not using named return values e.g. (clientIDs []string). I think it's more readable to be more explicit with and just declare the slice next to its usage

i.e.

        var clientIDs []string
	for ; iterator.Valid(); iterator.Next() {
                ...
		clientIDs = append(clientIDs, clientID)
	}

WDYT?

store := ctx.KVStore(k.storeKey)
prefix := host.PrefixedClientStoreKey(clientType)
iterator := sdk.KVStorePrefixIterator(store, prefix)

defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
path := string(iterator.Key())
if !strings.Contains(path, host.KeyClientState) {
// skip non client state keys
continue
}

clientID := host.MustParseClientStatePath(path)
clientIDs = append(clientIDs, clientID)
}

return clientIDs
}

// ClientStore returns isolated prefix store for each client so they can read/write in separate
// namespace without being able to read/write other client's data
func (k Keeper) ClientStore(ctx sdk.Context, clientID string) sdk.KVStore {
Expand Down
35 changes: 35 additions & 0 deletions modules/core/02-client/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -386,3 +386,38 @@ func (suite KeeperTestSuite) TestGetAllConsensusStates() {
consStates := suite.chainA.App.GetIBCKeeper().ClientKeeper.GetAllConsensusStates(suite.chainA.GetContext())
suite.Require().Equal(expConsensusStates, consStates, "%s \n\n%s", expConsensusStates, consStates)
}

func (suite KeeperTestSuite) TestGetAllClientIDsOfType() {
paths := []*ibctesting.Path{
ibctesting.NewPath(suite.chainA, suite.chainB),
ibctesting.NewPath(suite.chainA, suite.chainB),
ibctesting.NewPath(suite.chainA, suite.chainB),
}

solomachines := []*ibctesting.Solomachine{
ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "06-solomachine-0", "testing", 1),
ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "06-solomachine-1", "testing", 4),
}

var (
tmClientIDs = make([]string, len(paths))
smClientIDs = make([]string, len(solomachines))
)

// create tendermint clients
for i, path := range paths {
suite.coordinator.SetupClients(path)
tmClientIDs[i] = path.EndpointA.ClientID
}

// create solomachine clients
for i, sm := range solomachines {
smClientIDs[i] = sm.CreateClient(suite.chainA)
}

clientIDs := suite.chainA.GetSimApp().IBCKeeper.ClientKeeper.GetAllClientIDsOfType(suite.chainA.GetContext(), exported.Tendermint)
suite.Require().Equal(tmClientIDs, clientIDs)

clientIDs = suite.chainA.GetSimApp().IBCKeeper.ClientKeeper.GetAllClientIDsOfType(suite.chainA.GetContext(), exported.Solomachine)
suite.Require().Equal(smClientIDs, clientIDs)
}
2 changes: 1 addition & 1 deletion modules/core/02-client/migrations/v7/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ func handleLocalhostMigration(ctx sdk.Context, store sdk.KVStore, cdc codec.Bina
// for tendermint clients is included as only one tendermint clientID is required for
// v7 migrations.
func collectClients(ctx sdk.Context, store sdk.KVStore, clientType string) (clients []string, err error) {
clientPrefix := []byte(fmt.Sprintf("%s/%s", host.KeyClientStorePrefix, clientType))
clientPrefix := host.PrefixedClientStoreKey(clientType)
iterator := sdk.KVStorePrefixIterator(store, clientPrefix)

defer iterator.Close()
Expand Down
12 changes: 12 additions & 0 deletions modules/core/24-host/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,18 @@ func FullClientKey(clientID string, path []byte) []byte {
return []byte(FullClientPath(clientID, string(path)))
}

// PrefixedClientStorePath takes a client type and returns a prefixed key path
// which can be used to iterate over client stores belonging to a certain client type.
func PrefixedClientStorePath(clientType string) string {
return fmt.Sprintf("%s/%s", KeyClientStorePrefix, clientType)
}

// PrefixedClientStoreKey takes a client type and returns a prefixed key
// which can be used to iterate over client stores belonging to a certain client type.
func PrefixedClientStoreKey(clientType string) []byte {
return []byte(PrefixedClientStorePath(clientType))
}

// ICS02
// The following paths are the keys to the store as defined in https://github.com/cosmos/ibc/tree/master/spec/core/ics-002-client-semantics#path-space

Expand Down