From 7b3fa480cf142a7deaa04cbc8bbdf6d8a5008560 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Colin=20Axn=C3=A9r?= <25233464+colin-axner@users.noreply.github.com> Date: Wed, 30 Nov 2022 15:17:51 +0100 Subject: [PATCH 1/4] refactor: rename IterateClients to IterateClientStates, add a prefix argument --- modules/core/02-client/keeper/keeper.go | 14 ++++++++------ modules/core/03-connection/keeper/keeper.go | 2 +- .../core/03-connection/types/expected_keepers.go | 2 +- modules/core/24-host/keys.go | 14 ++++++++++++++ 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/modules/core/02-client/keeper/keeper.go b/modules/core/02-client/keeper/keeper.go index d98e523624b..7e62bdcef27 100644 --- a/modules/core/02-client/keeper/keeper.go +++ b/modules/core/02-client/keeper/keeper.go @@ -147,7 +147,7 @@ func (k Keeper) IterateConsensusStates(ctx sdk.Context, cb func(clientID string, // GetAllGenesisClients returns all the clients in state with their client ids returned as IdentifiedClientState func (k Keeper) GetAllGenesisClients(ctx sdk.Context) types.IdentifiedClientStates { var genClients types.IdentifiedClientStates - k.IterateClients(ctx, func(clientID string, cs exported.ClientState) bool { + k.IterateClientStates(ctx, nil, func(clientID string, cs exported.ClientState) bool { genClients = append(genClients, types.NewIdentifiedClientState(clientID, cs)) return false }) @@ -350,12 +350,12 @@ func (k Keeper) SetUpgradedConsensusState(ctx sdk.Context, planHeight int64, bz return k.upgradeKeeper.SetUpgradedConsensusState(ctx, planHeight, bz) } -// IterateClients provides an iterator over all stored light client State +// IterateClientStates provides an iterator over all stored light client State // objects. For each State object, cb will be called. If the cb returns true, // the iterator will close and stop. -func (k Keeper) IterateClients(ctx sdk.Context, cb func(clientID string, cs exported.ClientState) bool) { +func (k Keeper) IterateClientStates(ctx sdk.Context, prefix []byte, cb func(clientID string, cs exported.ClientState) bool) { store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, host.KeyClientStorePrefix) + iterator := sdk.KVStorePrefixIterator(store, host.PrefixedClientStoreKey(prefix)) defer iterator.Close() for ; iterator.Valid(); iterator.Next() { @@ -375,11 +375,13 @@ func (k Keeper) IterateClients(ctx sdk.Context, cb func(clientID string, cs expo } // GetAllClients returns all stored light client State objects. -func (k Keeper) GetAllClients(ctx sdk.Context) (states []exported.ClientState) { - k.IterateClients(ctx, func(_ string, state exported.ClientState) bool { +func (k Keeper) GetAllClients(ctx sdk.Context) []exported.ClientState { + var states []exported.ClientState + k.IterateClientStates(ctx, nil, func(_ string, state exported.ClientState) bool { states = append(states, state) return false }) + return states } diff --git a/modules/core/03-connection/keeper/keeper.go b/modules/core/03-connection/keeper/keeper.go index 35a1a764319..0a02f2b904a 100644 --- a/modules/core/03-connection/keeper/keeper.go +++ b/modules/core/03-connection/keeper/keeper.go @@ -146,7 +146,7 @@ func (k Keeper) SetNextConnectionSequence(ctx sdk.Context, sequence uint64) { // no paths are stored. func (k Keeper) GetAllClientConnectionPaths(ctx sdk.Context) []types.ConnectionPaths { var allConnectionPaths []types.ConnectionPaths - k.clientKeeper.IterateClients(ctx, func(clientID string, cs exported.ClientState) bool { + k.clientKeeper.IterateClientStates(ctx, nil, func(clientID string, cs exported.ClientState) bool { paths, found := k.GetClientConnectionPaths(ctx, clientID) if !found { // continue when connection handshake is not initialized diff --git a/modules/core/03-connection/types/expected_keepers.go b/modules/core/03-connection/types/expected_keepers.go index e7294d2ed63..264b844e756 100644 --- a/modules/core/03-connection/types/expected_keepers.go +++ b/modules/core/03-connection/types/expected_keepers.go @@ -12,6 +12,6 @@ type ClientKeeper interface { GetClientConsensusState(ctx sdk.Context, clientID string, height exported.Height) (exported.ConsensusState, bool) GetSelfConsensusState(ctx sdk.Context, height exported.Height) (exported.ConsensusState, error) ValidateSelfClient(ctx sdk.Context, clientState exported.ClientState) error - IterateClients(ctx sdk.Context, cb func(string, exported.ClientState) bool) + IterateClientStates(ctx sdk.Context, prefix []byte, cb func(string, exported.ClientState) bool) ClientStore(ctx sdk.Context, clientID string) sdk.KVStore } diff --git a/modules/core/24-host/keys.go b/modules/core/24-host/keys.go index b1d4a8bedfd..720bf6bb5f1 100644 --- a/modules/core/24-host/keys.go +++ b/modules/core/24-host/keys.go @@ -55,6 +55,20 @@ func FullClientKey(clientID string, path []byte) []byte { return []byte(FullClientPath(clientID, string(path))) } +// PrefixedClientStorePath returns a key path which can be used for prefixed +// key store iteration. The prefix may be a clientType, clientID, or any +// valid key prefix which may be concatenated with the client store constant. +func PrefixedClientStorePath(prefix []byte) string { + return fmt.Sprintf("%s/%s", KeyClientStorePrefix, prefix) +} + +// PrefixedClientStoreKey returns a key which can be used for prefixed +// key store iteration. The prefix may be a clientType, clientID, or any +// valid key prefix which may be concatenated with the client store constant. +func PrefixedClientStoreKey(prefix []byte) []byte { + return []byte(PrefixedClientStorePath(prefix)) +} + // 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 From e391ec94854a8c22915200d28787853347f6b6b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Colin=20Axn=C3=A9r?= <25233464+colin-axner@users.noreply.github.com> Date: Wed, 30 Nov 2022 15:34:49 +0100 Subject: [PATCH 2/4] test: add IterateClientStates test --- modules/core/02-client/keeper/keeper_test.go | 64 ++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/modules/core/02-client/keeper/keeper_test.go b/modules/core/02-client/keeper/keeper_test.go index f02da108b20..539c14a3899 100644 --- a/modules/core/02-client/keeper/keeper_test.go +++ b/modules/core/02-client/keeper/keeper_test.go @@ -386,3 +386,67 @@ 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) TestIterateClientStates() { + 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 ( + expTMClientIDs = make([]string, len(paths)) + expSMClientIDs = make([]string, len(solomachines)) + ) + + // create tendermint clients + for i, path := range paths { + suite.coordinator.SetupClients(path) + expTMClientIDs[i] = path.EndpointA.ClientID + } + + // create solomachine clients + for i, sm := range solomachines { + expSMClientIDs[i] = sm.CreateClient(suite.chainA) + } + + testCases := []struct { + name string + prefix []byte + expClientIDs []string + }{ + { + "all clientIDs", + nil, + append(expSMClientIDs, expTMClientIDs...), + }, + { + "tendermint clientIDs", + []byte(exported.Tendermint), + expTMClientIDs, + }, + { + "solo machine clientIDs", + []byte(exported.Solomachine), + expSMClientIDs, + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + var clientIDs []string + suite.chainA.GetSimApp().IBCKeeper.ClientKeeper.IterateClientStates(suite.chainA.GetContext(), tc.prefix, func(clientID string, _ exported.ClientState) bool { + clientIDs = append(clientIDs, clientID) + return false + }) + + suite.Require().Equal(tc.expClientIDs, clientIDs) + }) + } +} From fd09362c412720145ef28e19f6196f13afe390ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Colin=20Axn=C3=A9r?= <25233464+colin-axner@users.noreply.github.com> Date: Wed, 30 Nov 2022 15:36:49 +0100 Subject: [PATCH 3/4] chore: add changelog entry --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 71629f83a02..165827e3553 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### API Breaking +* (core/02-client) [\#2856](https://github.com/cosmos/ibc-go/pull/2856) Rename `IterateClients` to `IterateClientStates`. The function now takes a prefix argument which may be used for prefix iteration over client the client store. * (apps/27-interchain-accounts) [\#2607](https://github.com/cosmos/ibc-go/pull/2607) `SerializeCosmosTx` now takes in a `[]proto.Message` instead of `[]sdk.Msg`. * (apps/transfer) [\#2446](https://github.com/cosmos/ibc-go/pull/2446) Remove `SendTransfer` function in favor of a private `sendTransfer` function. All IBC transfers must be initiated with `MsgTransfer`. * (apps/29-fee) [\#2395](https://github.com/cosmos/ibc-go/pull/2395) Remove param space from ics29 NewKeeper function. The field was unused. @@ -115,6 +116,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### Features +* (core/24-host) [\#2856](https://github.com/cosmos/ibc-go/pull/2856) 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. From 89770cdef494b47a402884d14e1227dbe9418425 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?colin=20axn=C3=A9r?= <25233464+colin-axner@users.noreply.github.com> Date: Wed, 30 Nov 2022 15:38:53 +0100 Subject: [PATCH 4/4] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 165827e3553..1bdb28e97f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,7 +42,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ ### API Breaking -* (core/02-client) [\#2856](https://github.com/cosmos/ibc-go/pull/2856) Rename `IterateClients` to `IterateClientStates`. The function now takes a prefix argument which may be used for prefix iteration over client the client store. +* (core/02-client) [\#2856](https://github.com/cosmos/ibc-go/pull/2856) Rename `IterateClients` to `IterateClientStates`. The function now takes a prefix argument which may be used for prefix iteration over the client store. * (apps/27-interchain-accounts) [\#2607](https://github.com/cosmos/ibc-go/pull/2607) `SerializeCosmosTx` now takes in a `[]proto.Message` instead of `[]sdk.Msg`. * (apps/transfer) [\#2446](https://github.com/cosmos/ibc-go/pull/2446) Remove `SendTransfer` function in favor of a private `sendTransfer` function. All IBC transfers must be initiated with `MsgTransfer`. * (apps/29-fee) [\#2395](https://github.com/cosmos/ibc-go/pull/2395) Remove param space from ics29 NewKeeper function. The field was unused.