Skip to content

Commit 5cf6528

Browse files
authored
refactor: remove localhost client implementation (#1187)
* refactor: remove localhost light client implementation * chore: readding CreateLocalhost field * chore: readding createLocalhost field * chore: changelog * fix: BeginBlocker * fix: removing CreateLocalhost * chore: remove unused code * refactor: keeper tests * refactor: genesis type test add case for invalid client type * fix: add back tests * fix: remove unncessary if statement
1 parent 3c7358b commit 5cf6528

34 files changed

+70
-1694
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
4343
### State Machine Breaking
4444

4545
### Improvements
46+
* (modules/light-clients/09-localhost) [\#1187](https://github.com/cosmos/ibc-go/pull/1187/) Removing localhost light client implementation as it is not functional.
4647
* [\#1186](https://github.com/cosmos/ibc-go/pull/1186/files) Removing `GetRoot` function from ConsensusState interface in `02-client`. `GetRoot` is unused by core IBC.
4748
* (modules/core/02-client) [\#1196](https://github.com/cosmos/ibc-go/pull/1196) Adding VerifyClientMessage to ClientState interface.
4849
* (modules/core/02-client) [\#1198](https://github.com/cosmos/ibc-go/pull/1198) Adding UpdateStateOnMisbehaviour to ClientState interface.

README.md

-2
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,6 @@ The Inter-Blockchain Communication protocol (IBC) allows blockchains to talk to
5959

6060
3.2 [ICS 06 Solo Machine](https://github.com/cosmos/ibc-go/tree/main/modules/light-clients/06-solomachine)
6161

62-
Note: The localhost client is currently non-functional.
63-
6462
## Roadmap
6563

6664
For an overview of upcoming changes to ibc-go take a look at the [roadmap](./docs/roadmap/roadmap.md).

docs/OLD_README.md

+1-3
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,6 @@ For the general specification please refer to the [Interchain Standards](https:/
2828

2929
3.2 [Tendermint Client](./../light-clients/07-tendermint/spec/README.md)
3030

31-
3.3 [Localhost Client](./../light-clients/09-localhost/spec/README.md)
32-
3331
## Implementation Details
3432

3533
As stated above, the IBC implementation on the Cosmos SDK introduces some changes
@@ -114,4 +112,4 @@ x/ibc
114112
│   └── 09-localhost/
115113
└── testing/
116114
```
117-
<!-- markdown-link-check-enable-->
115+
<!-- markdown-link-check-enable-->

docs/ibc/integration.md

-11
Original file line numberDiff line numberDiff line change
@@ -175,17 +175,6 @@ at each height during the `BeginBlock` call. The historical info is required to
175175
past historical info at any given height in order to verify the light client `ConsensusState` during the
176176
connection handhake.
177177
178-
The IBC module also has
179-
[`BeginBlock`](https://github.com/cosmos/ibc-go/blob/main/modules/core/02-client/abci.go) logic as
180-
well. This is optional as it is only required if your application uses the [localhost
181-
client](https://github.com/cosmos/ibc/blob/master/spec/client/ics-009-loopback-client) to connect two
182-
different modules from the same chain.
183-
184-
::: tip
185-
Only register the ibc module to the `SetOrderBeginBlockers` if your application will use the
186-
localhost (_aka_ loopback) client.
187-
:::
188-
189178
```go
190179
// app.go
191180
func NewApp(...args) *App {

docs/ibc/proto-docs.md

-36
Original file line numberDiff line numberDiff line change
@@ -217,9 +217,6 @@
217217
- [ibc/core/types/v1/genesis.proto](#ibc/core/types/v1/genesis.proto)
218218
- [GenesisState](#ibc.core.types.v1.GenesisState)
219219

220-
- [ibc/lightclients/localhost/v1/localhost.proto](#ibc/lightclients/localhost/v1/localhost.proto)
221-
- [ClientState](#ibc.lightclients.localhost.v1.ClientState)
222-
223220
- [ibc/lightclients/solomachine/v1/solomachine.proto](#ibc/lightclients/solomachine/v1/solomachine.proto)
224221
- [ChannelStateData](#ibc.lightclients.solomachine.v1.ChannelStateData)
225222
- [ClientState](#ibc.lightclients.solomachine.v1.ClientState)
@@ -3242,39 +3239,6 @@ GenesisState defines the ibc module's genesis state.
32423239

32433240

32443241

3245-
<!-- end messages -->
3246-
3247-
<!-- end enums -->
3248-
3249-
<!-- end HasExtensions -->
3250-
3251-
<!-- end services -->
3252-
3253-
3254-
3255-
<a name="ibc/lightclients/localhost/v1/localhost.proto"></a>
3256-
<p align="right"><a href="#top">Top</a></p>
3257-
3258-
## ibc/lightclients/localhost/v1/localhost.proto
3259-
3260-
3261-
3262-
<a name="ibc.lightclients.localhost.v1.ClientState"></a>
3263-
3264-
### ClientState
3265-
ClientState defines a loopback (localhost) client. It requires (read-only)
3266-
access to keys outside the client prefix.
3267-
3268-
3269-
| Field | Type | Label | Description |
3270-
| ----- | ---- | ----- | ----------- |
3271-
| `chain_id` | [string](#string) | | self chain ID |
3272-
| `height` | [ibc.core.client.v1.Height](#ibc.core.client.v1.Height) | | self latest block height |
3273-
3274-
3275-
3276-
3277-
32783242
<!-- end messages -->
32793243

32803244
<!-- end enums -->

modules/core/02-client/abci.go

+1-12
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,10 @@ import (
44
sdk "github.com/cosmos/cosmos-sdk/types"
55

66
"github.com/cosmos/ibc-go/v3/modules/core/02-client/keeper"
7-
"github.com/cosmos/ibc-go/v3/modules/core/exported"
87
ibctmtypes "github.com/cosmos/ibc-go/v3/modules/light-clients/07-tendermint/types"
98
)
109

11-
// BeginBlocker updates an existing localhost client with the latest block height.
10+
// BeginBlocker is used to perform IBC client upgrades
1211
func BeginBlocker(ctx sdk.Context, k keeper.Keeper) {
1312
plan, found := k.GetUpgradePlan(ctx)
1413
if found {
@@ -29,14 +28,4 @@ func BeginBlocker(ctx sdk.Context, k keeper.Keeper) {
2928
k.SetUpgradedConsensusState(ctx, plan.Height, bz)
3029
}
3130
}
32-
33-
_, found = k.GetClientState(ctx, exported.Localhost)
34-
if !found {
35-
return
36-
}
37-
38-
// update the localhost client with the latest block height
39-
if err := k.UpdateClient(ctx, exported.Localhost, nil); err != nil {
40-
panic(err)
41-
}
4231
}

modules/core/02-client/abci_test.go

+1-19
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,14 @@ package client_test
33
import (
44
"testing"
55

6-
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
76
"github.com/stretchr/testify/suite"
87
abci "github.com/tendermint/tendermint/abci/types"
98
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
109

10+
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
1111
client "github.com/cosmos/ibc-go/v3/modules/core/02-client"
1212
"github.com/cosmos/ibc-go/v3/modules/core/02-client/types"
13-
"github.com/cosmos/ibc-go/v3/modules/core/exported"
1413
ibctmtypes "github.com/cosmos/ibc-go/v3/modules/light-clients/07-tendermint/types"
15-
localhosttypes "github.com/cosmos/ibc-go/v3/modules/light-clients/09-localhost/types"
1614
ibctesting "github.com/cosmos/ibc-go/v3/testing"
1715
)
1816

@@ -30,36 +28,20 @@ func (suite *ClientTestSuite) SetupTest() {
3028

3129
suite.chainA = suite.coordinator.GetChain(ibctesting.GetChainID(1))
3230
suite.chainB = suite.coordinator.GetChain(ibctesting.GetChainID(2))
33-
34-
// set localhost client
35-
revision := types.ParseChainID(suite.chainA.GetContext().ChainID())
36-
localHostClient := localhosttypes.NewClientState(
37-
suite.chainA.GetContext().ChainID(), types.NewHeight(revision, uint64(suite.chainA.GetContext().BlockHeight())),
38-
)
39-
suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientState(suite.chainA.GetContext(), exported.Localhost, localHostClient)
4031
}
4132

4233
func TestClientTestSuite(t *testing.T) {
4334
suite.Run(t, new(ClientTestSuite))
4435
}
4536

4637
func (suite *ClientTestSuite) TestBeginBlocker() {
47-
prevHeight := types.GetSelfHeight(suite.chainA.GetContext())
48-
49-
localHostClient := suite.chainA.GetClientState(exported.Localhost)
50-
suite.Require().Equal(prevHeight, localHostClient.GetLatestHeight())
51-
5238
for i := 0; i < 10; i++ {
5339
// increment height
5440
suite.coordinator.CommitBlock(suite.chainA, suite.chainB)
5541

5642
suite.Require().NotPanics(func() {
5743
client.BeginBlocker(suite.chainA.GetContext(), suite.chainA.App.GetIBCKeeper().ClientKeeper)
5844
}, "BeginBlocker shouldn't panic")
59-
60-
localHostClient = suite.chainA.GetClientState(exported.Localhost)
61-
suite.Require().Equal(prevHeight.Increment(), localHostClient.GetLatestHeight())
62-
prevHeight = localHostClient.GetLatestHeight().(types.Height)
6345
}
6446
}
6547

modules/core/02-client/genesis.go

+5-9
Original file line numberDiff line numberDiff line change
@@ -46,25 +46,21 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, gs types.GenesisState) {
4646
}
4747

4848
k.SetNextClientSequence(ctx, gs.NextClientSequence)
49-
50-
// NOTE: localhost creation is specifically disallowed for the time being.
51-
// Issue: https://github.com/cosmos/cosmos-sdk/issues/7871
5249
}
5350

5451
// ExportGenesis returns the ibc client submodule's exported genesis.
55-
// NOTE: CreateLocalhost should always be false on export since a
56-
// created localhost will be included in the exported clients.
5752
func ExportGenesis(ctx sdk.Context, k keeper.Keeper) types.GenesisState {
5853
genClients := k.GetAllGenesisClients(ctx)
5954
clientsMetadata, err := k.GetAllClientMetadata(ctx, genClients)
6055
if err != nil {
6156
panic(err)
6257
}
6358
return types.GenesisState{
64-
Clients: genClients,
65-
ClientsMetadata: clientsMetadata,
66-
ClientsConsensus: k.GetAllConsensusStates(ctx),
67-
Params: k.GetParams(ctx),
59+
Clients: genClients,
60+
ClientsMetadata: clientsMetadata,
61+
ClientsConsensus: k.GetAllConsensusStates(ctx),
62+
Params: k.GetParams(ctx),
63+
// Warning: CreateLocalhost is deprecated
6864
CreateLocalhost: false,
6965
NextClientSequence: k.GetNextClientSequence(ctx),
7066
}

modules/core/02-client/keeper/client.go

+2-10
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,7 @@ func (k Keeper) CreateClient(
3636
return "", err
3737
}
3838

39-
// check if consensus state is nil in case the created client is Localhost
40-
if consensusState != nil {
41-
k.SetClientConsensusState(ctx, clientID, clientState.GetLatestHeight(), consensusState)
42-
}
39+
k.SetClientConsensusState(ctx, clientID, clientState.GetLatestHeight(), consensusState)
4340

4441
k.Logger(ctx).Info("client created at height", "client-id", clientID, "height", clientState.GetLatestHeight().String())
4542

@@ -98,12 +95,7 @@ func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.C
9895
// Else the update was proof of misbehaviour and we must emit appropriate misbehaviour events.
9996
if status := newClientState.Status(ctx, clientStore, k.cdc); status != exported.Frozen {
10097
// if update is not misbehaviour then update the consensus state
101-
// we don't set consensus state for localhost client
102-
if header != nil && clientID != exported.Localhost {
103-
k.SetClientConsensusState(ctx, clientID, header.GetHeight(), newConsensusState)
104-
} else {
105-
consensusHeight = types.GetSelfHeight(ctx)
106-
}
98+
k.SetClientConsensusState(ctx, clientID, header.GetHeight(), newConsensusState)
10799

108100
k.Logger(ctx).Info("client state updated", "client-id", clientID, "height", consensusHeight.String())
109101

modules/core/02-client/keeper/client_test.go

+2-15
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ import (
1212
clienttypes "github.com/cosmos/ibc-go/v3/modules/core/02-client/types"
1313
commitmenttypes "github.com/cosmos/ibc-go/v3/modules/core/23-commitment/types"
1414
"github.com/cosmos/ibc-go/v3/modules/core/exported"
15+
solomachinetypes "github.com/cosmos/ibc-go/v3/modules/light-clients/06-solomachine/types"
1516
ibctmtypes "github.com/cosmos/ibc-go/v3/modules/light-clients/07-tendermint/types"
16-
localhosttypes "github.com/cosmos/ibc-go/v3/modules/light-clients/09-localhost/types"
1717
ibctesting "github.com/cosmos/ibc-go/v3/testing"
1818
ibctestingmock "github.com/cosmos/ibc-go/v3/testing/mock"
1919
)
@@ -25,7 +25,7 @@ func (suite *KeeperTestSuite) TestCreateClient() {
2525
expPass bool
2626
}{
2727
{"success", ibctmtypes.NewClientState(testChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false), true},
28-
{"client type not supported", localhosttypes.NewClientState(testChainID, clienttypes.NewHeight(0, 1)), false},
28+
{"client type not supported", solomachinetypes.NewClientState(0, &solomachinetypes.ConsensusState{suite.solomachine.ConsensusState().PublicKey, suite.solomachine.Diversifier, suite.solomachine.Time}, false), false},
2929
}
3030

3131
for i, tc := range cases {
@@ -252,19 +252,6 @@ func (suite *KeeperTestSuite) TestUpdateClientTendermint() {
252252
}
253253
}
254254

255-
func (suite *KeeperTestSuite) TestUpdateClientLocalhost() {
256-
revision := types.ParseChainID(suite.chainA.ChainID)
257-
var localhostClient exported.ClientState = localhosttypes.NewClientState(suite.chainA.ChainID, types.NewHeight(revision, uint64(suite.chainA.GetContext().BlockHeight())))
258-
259-
ctx := suite.chainA.GetContext().WithBlockHeight(suite.chainA.GetContext().BlockHeight() + 1)
260-
err := suite.chainA.App.GetIBCKeeper().ClientKeeper.UpdateClient(ctx, exported.Localhost, nil)
261-
suite.Require().NoError(err)
262-
263-
clientState, found := suite.chainA.App.GetIBCKeeper().ClientKeeper.GetClientState(ctx, exported.Localhost)
264-
suite.Require().True(found)
265-
suite.Require().Equal(localhostClient.GetLatestHeight().(types.Height).Increment(), clientState.GetLatestHeight())
266-
}
267-
268255
func (suite *KeeperTestSuite) TestUpgradeClient() {
269256
var (
270257
path *ibctesting.Path

modules/core/02-client/keeper/grpc_query_test.go

+1-7
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ func (suite *KeeperTestSuite) TestQueryClientStates() {
140140
idcs := types.NewIdentifiedClientState(path1.EndpointA.ClientID, clientStateA1)
141141
idcs2 := types.NewIdentifiedClientState(path2.EndpointA.ClientID, clientStateA2)
142142

143-
// order is sorted by client id, localhost is last
143+
// order is sorted by client id
144144
expClientStates = types.IdentifiedClientStates{idcs, idcs2}.Sort()
145145
req = &types.QueryClientStatesRequest{
146146
Pagination: &query.PageRequest{
@@ -156,13 +156,7 @@ func (suite *KeeperTestSuite) TestQueryClientStates() {
156156
for _, tc := range testCases {
157157
suite.Run(fmt.Sprintf("Case %s", tc.msg), func() {
158158
suite.SetupTest() // reset
159-
expClientStates = nil
160-
161159
tc.malleate()
162-
// always add localhost which is created by default in init genesis
163-
localhostClientState := suite.chainA.GetClientState(exported.Localhost)
164-
identifiedLocalhost := types.NewIdentifiedClientState(exported.Localhost, localhostClientState)
165-
expClientStates = append(expClientStates, identifiedLocalhost)
166160

167161
ctx := sdk.WrapSDKContext(suite.chainA.GetContext())
168162

modules/core/02-client/keeper/keeper_test.go

+9-20
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ import (
1919
"github.com/cosmos/ibc-go/v3/modules/core/02-client/types"
2020
commitmenttypes "github.com/cosmos/ibc-go/v3/modules/core/23-commitment/types"
2121
"github.com/cosmos/ibc-go/v3/modules/core/exported"
22+
solomachinetypes "github.com/cosmos/ibc-go/v3/modules/light-clients/06-solomachine/types"
2223
ibctmtypes "github.com/cosmos/ibc-go/v3/modules/light-clients/07-tendermint/types"
23-
localhosttypes "github.com/cosmos/ibc-go/v3/modules/light-clients/09-localhost/types"
2424
ibctesting "github.com/cosmos/ibc-go/v3/testing"
2525
ibctestingmock "github.com/cosmos/ibc-go/v3/testing/mock"
2626
"github.com/cosmos/ibc-go/v3/testing/simapp"
@@ -65,8 +65,8 @@ type KeeperTestSuite struct {
6565
privVal tmtypes.PrivValidator
6666
now time.Time
6767
past time.Time
68-
69-
signers map[string]tmtypes.PrivValidator
68+
solomachine *ibctesting.Solomachine
69+
signers map[string]tmtypes.PrivValidator
7070

7171
// TODO: deprecate
7272
queryClient types.QueryClient
@@ -122,12 +122,7 @@ func (suite *KeeperTestSuite) SetupTest() {
122122
app.StakingKeeper.SetHistoricalInfo(suite.ctx, int64(i), &hi)
123123
}
124124

125-
// add localhost client
126-
revision := types.ParseChainID(suite.chainA.ChainID)
127-
localHostClient := localhosttypes.NewClientState(
128-
suite.chainA.ChainID, types.NewHeight(revision, uint64(suite.chainA.GetContext().BlockHeight())),
129-
)
130-
suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientState(suite.chainA.GetContext(), exported.Localhost, localHostClient)
125+
suite.solomachine = ibctesting.NewSolomachine(suite.T(), suite.chainA.Codec, "solomachinesingle", "testing", 1)
131126

132127
// TODO: deprecate
133128
queryHelper := baseapp.NewQueryServerTestHelper(suite.ctx, app.InterfaceRegistry())
@@ -177,11 +172,6 @@ func (suite *KeeperTestSuite) TestValidateSelfClient() {
177172
ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, commitmenttypes.GetSDKSpecs(), nil, false, false),
178173
true,
179174
},
180-
{
181-
"invalid client type",
182-
localhosttypes.NewClientState(suite.chainA.ChainID, testClientHeight),
183-
false,
184-
},
185175
{
186176
"frozen client",
187177
&ibctmtypes.ClientState{suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeight, testClientHeight, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false},
@@ -197,6 +187,11 @@ func (suite *KeeperTestSuite) TestValidateSelfClient() {
197187
ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, types.NewHeight(0, uint64(suite.chainA.GetContext().BlockHeight())), commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false),
198188
false,
199189
},
190+
{
191+
"invalid client type",
192+
solomachinetypes.NewClientState(0, &solomachinetypes.ConsensusState{suite.solomachine.ConsensusState().PublicKey, suite.solomachine.Diversifier, suite.solomachine.Time}, false),
193+
false,
194+
},
200195
{
201196
"invalid client revision",
202197
ibctmtypes.NewClientState(suite.chainA.ChainID, ibctmtypes.DefaultTrustLevel, trustingPeriod, ubdPeriod, maxClockDrift, testClientHeightRevision1, commitmenttypes.GetSDKSpecs(), ibctesting.UpgradePath, false, false),
@@ -256,11 +251,6 @@ func (suite KeeperTestSuite) TestGetAllGenesisClients() {
256251
expGenClients[i] = types.NewIdentifiedClientState(clientIDs[i], expClients[i])
257252
}
258253

259-
// add localhost client
260-
localHostClient, found := suite.chainA.App.GetIBCKeeper().ClientKeeper.GetClientState(suite.chainA.GetContext(), exported.Localhost)
261-
suite.Require().True(found)
262-
expGenClients = append(expGenClients, types.NewIdentifiedClientState(exported.Localhost, localHostClient))
263-
264254
genClients := suite.chainA.App.GetIBCKeeper().ClientKeeper.GetAllGenesisClients(suite.chainA.GetContext())
265255

266256
suite.Require().Equal(expGenClients.Sort(), genClients)
@@ -287,7 +277,6 @@ func (suite KeeperTestSuite) TestGetAllGenesisMetadata() {
287277

288278
genClients := []types.IdentifiedClientState{
289279
types.NewIdentifiedClientState("07-tendermint-1", &ibctmtypes.ClientState{}), types.NewIdentifiedClientState("clientB", &ibctmtypes.ClientState{}),
290-
types.NewIdentifiedClientState("clientC", &ibctmtypes.ClientState{}), types.NewIdentifiedClientState("clientD", &localhosttypes.ClientState{}),
291280
}
292281

293282
suite.chainA.App.GetIBCKeeper().ClientKeeper.SetAllClientMetadata(suite.chainA.GetContext(), expectedGenMetadata)

modules/core/02-client/keeper/proposal.go

+1-6
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,11 @@ import (
1313
// ClientUpdateProposal will retrieve the subject and substitute client.
1414
// A callback will occur to the subject client state with the client
1515
// prefixed store being provided for both the subject and the substitute client.
16-
// The localhost client is not allowed to be modified with a proposal. The IBC
17-
// client implementations are responsible for validating the parameters of the
16+
// The IBC client implementations are responsible for validating the parameters of the
1817
// subtitute (enusring they match the subject's parameters) as well as copying
1918
// the necessary consensus states from the subtitute to the subject client
2019
// store. The substitute must be Active and the subject must not be Active.
2120
func (k Keeper) ClientUpdateProposal(ctx sdk.Context, p *types.ClientUpdateProposal) error {
22-
if p.SubjectClientId == exported.Localhost || p.SubstituteClientId == exported.Localhost {
23-
return sdkerrors.Wrap(types.ErrInvalidUpdateClientProposal, "cannot update localhost client with proposal")
24-
}
25-
2621
subjectClientState, found := k.GetClientState(ctx, p.SubjectClientId)
2722
if !found {
2823
return sdkerrors.Wrapf(types.ErrClientNotFound, "subject client with ID %s", p.SubjectClientId)

0 commit comments

Comments
 (0)