Skip to content

Commit e49ed07

Browse files
authored
backport-v7.8.x: self client/consensus state removal from connection handshake (#7128)
* refactor: remove self validation of client and consensus states in connection handshake * fix: tests + additional removal in msg validation * changelog * chore: add deprecation notice to protos
1 parent 88fd95e commit e49ed07

File tree

9 files changed

+96
-378
lines changed

9 files changed

+96
-378
lines changed

CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ Ref: https://keepachangelog.com/en/1.0.0/
3434

3535
# Changelog
3636

37+
## [v7.8.0]()
38+
39+
### State Machine Breaking
40+
41+
* (core/03-connection)[\#7128](https://github.com/cosmos/ibc-go/pull/7128) Remove verification of self client and consensus state from connection handshake.
42+
3743
## [v7.7.0](https://github.com/cosmos/ibc-go/releases/tag/v7.7.0) - 2024-07-29
3844

3945
### Dependencies

modules/core/03-connection/keeper/handshake.go

+8-73
Original file line numberDiff line numberDiff line change
@@ -72,37 +72,17 @@ func (k Keeper) ConnOpenTry(
7272
counterparty types.Counterparty, // counterpartyConnectionIdentifier, counterpartyPrefix and counterpartyClientIdentifier
7373
delayPeriod uint64,
7474
clientID string, // clientID of chainA
75-
clientState exported.ClientState, // clientState that chainA has for chainB
75+
_ exported.ClientState, // clientState that chainA has for chainB
7676
counterpartyVersions []exported.Version, // supported versions of chain A
7777
proofInit []byte, // proof that chainA stored connectionEnd in state (on ConnOpenInit)
78-
proofClient []byte, // proof that chainA stored a light client of chainB
79-
proofConsensus []byte, // proof that chainA stored chainB's consensus state at consensus height
78+
_ []byte, // proof that chainA stored a light client of chainB
79+
_ []byte, // proof that chainA stored chainB's consensus state at consensus height
8080
proofHeight exported.Height, // height at which relayer constructs proof of A storing connectionEnd in state
81-
consensusHeight exported.Height, // latest height of chain B which chain A has stored in its chain B client
81+
_ exported.Height, // latest height of chain B which chain A has stored in its chain B client
8282
) (string, error) {
8383
// generate a new connection
8484
connectionID := k.GenerateConnectionIdentifier(ctx)
8585

86-
// check that the consensus height the counterparty chain is using to store a representation
87-
// of this chain's consensus state is at a height in the past
88-
selfHeight := clienttypes.GetSelfHeight(ctx)
89-
if consensusHeight.GTE(selfHeight) {
90-
return "", sdkerrors.Wrapf(
91-
sdkerrors.ErrInvalidHeight,
92-
"consensus height is greater than or equal to the current block height (%s >= %s)", consensusHeight, selfHeight,
93-
)
94-
}
95-
96-
// validate client parameters of a chainB client stored on chainA
97-
if err := k.clientKeeper.ValidateSelfClient(ctx, clientState); err != nil {
98-
return "", err
99-
}
100-
101-
expectedConsensusState, err := k.clientKeeper.GetSelfConsensusState(ctx, consensusHeight)
102-
if err != nil {
103-
return "", sdkerrors.Wrapf(err, "self consensus state not found for height %s", consensusHeight.String())
104-
}
105-
10686
// expectedConnection defines Chain A's ConnectionEnd
10787
// NOTE: chain A's counterparty is chain B (i.e where this code is executed)
10888
// NOTE: chainA and chainB must have the same delay period
@@ -129,18 +109,6 @@ func (k Keeper) ConnOpenTry(
129109
return "", err
130110
}
131111

132-
// Check that ChainA stored the clientState provided in the msg
133-
if err := k.VerifyClientState(ctx, connection, proofHeight, proofClient, clientState); err != nil {
134-
return "", err
135-
}
136-
137-
// Check that ChainA stored the correct ConsensusState of chainB at the given consensusHeight
138-
if err := k.VerifyClientConsensusState(
139-
ctx, connection, proofHeight, consensusHeight, proofConsensus, expectedConsensusState,
140-
); err != nil {
141-
return "", err
142-
}
143-
144112
// store connection in chainB state
145113
if err := k.addConnectionToClient(ctx, clientID, connectionID); err != nil {
146114
return "", sdkerrors.Wrapf(err, "failed to add connection with ID %s to client with ID %s", connectionID, clientID)
@@ -165,25 +133,15 @@ func (k Keeper) ConnOpenTry(
165133
func (k Keeper) ConnOpenAck(
166134
ctx sdk.Context,
167135
connectionID string,
168-
clientState exported.ClientState, // client state for chainA on chainB
136+
_ exported.ClientState, // client state for chainA on chainB
169137
version *types.Version, // version that ChainB chose in ConnOpenTry
170138
counterpartyConnectionID string,
171139
proofTry []byte, // proof that connectionEnd was added to ChainB state in ConnOpenTry
172-
proofClient []byte, // proof of client state on chainB for chainA
173-
proofConsensus []byte, // proof that chainB has stored ConsensusState of chainA on its client
140+
_ []byte, // proof of client state on chainB for chainA
141+
_ []byte, // proof that chainB has stored ConsensusState of chainA on its client
174142
proofHeight exported.Height, // height that relayer constructed proofTry
175-
consensusHeight exported.Height, // latest height of chainA that chainB has stored on its chainA client
143+
_ exported.Height, // latest height of chainA that chainB has stored on its chainA client
176144
) error {
177-
// check that the consensus height the counterparty chain is using to store a representation
178-
// of this chain's consensus state is at a height in the past
179-
selfHeight := clienttypes.GetSelfHeight(ctx)
180-
if consensusHeight.GTE(selfHeight) {
181-
return sdkerrors.Wrapf(
182-
sdkerrors.ErrInvalidHeight,
183-
"consensus height is greater than or equal to the current block height (%s >= %s)", consensusHeight, selfHeight,
184-
)
185-
}
186-
187145
// Retrieve connection
188146
connection, found := k.GetConnection(ctx, connectionID)
189147
if !found {
@@ -206,17 +164,6 @@ func (k Keeper) ConnOpenAck(
206164
)
207165
}
208166

209-
// validate client parameters of a chainA client stored on chainB
210-
if err := k.clientKeeper.ValidateSelfClient(ctx, clientState); err != nil {
211-
return err
212-
}
213-
214-
// Retrieve chainA's consensus state at consensusheight
215-
expectedConsensusState, err := k.clientKeeper.GetSelfConsensusState(ctx, consensusHeight)
216-
if err != nil {
217-
return sdkerrors.Wrapf(err, "self consensus state not found for height %s", consensusHeight.String())
218-
}
219-
220167
prefix := k.GetCommitmentPrefix()
221168
expectedCounterparty := types.NewCounterparty(connection.ClientId, connectionID, commitmenttypes.NewMerklePrefix(prefix.Bytes()))
222169
expectedConnection := types.NewConnectionEnd(types.TRYOPEN, connection.Counterparty.ClientId, expectedCounterparty, []*types.Version{version}, connection.DelayPeriod)
@@ -229,18 +176,6 @@ func (k Keeper) ConnOpenAck(
229176
return err
230177
}
231178

232-
// Check that ChainB stored the clientState provided in the msg
233-
if err := k.VerifyClientState(ctx, connection, proofHeight, proofClient, clientState); err != nil {
234-
return err
235-
}
236-
237-
// Ensure that ChainB has stored the correct ConsensusState for chainA at the consensusHeight
238-
if err := k.VerifyClientConsensusState(
239-
ctx, connection, proofHeight, consensusHeight, proofConsensus, expectedConsensusState,
240-
); err != nil {
241-
return err
242-
}
243-
244179
k.Logger(ctx).Info("connection state updated", "connection-id", connectionID, "previous-state", "INIT", "new-state", "OPEN")
245180

246181
defer func() {

modules/core/03-connection/keeper/handshake_test.go

+1-141
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import (
77
"github.com/cosmos/ibc-go/v7/modules/core/03-connection/types"
88
host "github.com/cosmos/ibc-go/v7/modules/core/24-host"
99
"github.com/cosmos/ibc-go/v7/modules/core/exported"
10-
ibctm "github.com/cosmos/ibc-go/v7/modules/light-clients/07-tendermint"
1110
ibctesting "github.com/cosmos/ibc-go/v7/testing"
1211
)
1312

@@ -132,38 +131,6 @@ func (suite *KeeperTestSuite) TestConnOpenTry() {
132131
// retrieve client state of chainA to pass as counterpartyClient
133132
counterpartyClient = suite.chainA.GetClientState(path.EndpointA.ClientID)
134133
}, true},
135-
{"invalid counterparty client", func() {
136-
err := path.EndpointA.ConnOpenInit()
137-
suite.Require().NoError(err)
138-
139-
// retrieve client state of chainB to pass as counterpartyClient
140-
counterpartyClient = suite.chainA.GetClientState(path.EndpointA.ClientID)
141-
142-
// Set an invalid client of chainA on chainB
143-
tmClient, ok := counterpartyClient.(*ibctm.ClientState)
144-
suite.Require().True(ok)
145-
tmClient.ChainId = "wrongchainid"
146-
147-
suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientState(suite.chainA.GetContext(), path.EndpointA.ClientID, tmClient)
148-
}, false},
149-
{"consensus height >= latest height", func() {
150-
err := path.EndpointA.ConnOpenInit()
151-
suite.Require().NoError(err)
152-
153-
// retrieve client state of chainA to pass as counterpartyClient
154-
counterpartyClient = suite.chainA.GetClientState(path.EndpointA.ClientID)
155-
156-
consensusHeight = clienttypes.GetSelfHeight(suite.chainB.GetContext())
157-
}, false},
158-
{"self consensus state not found", func() {
159-
err := path.EndpointA.ConnOpenInit()
160-
suite.Require().NoError(err)
161-
162-
// retrieve client state of chainA to pass as counterpartyClient
163-
counterpartyClient = suite.chainA.GetClientState(path.EndpointA.ClientID)
164-
165-
consensusHeight = clienttypes.NewHeight(0, 1)
166-
}, false},
167134
{"counterparty versions is empty", func() {
168135
err := path.EndpointA.ConnOpenInit()
169136
suite.Require().NoError(err)
@@ -189,35 +156,6 @@ func (suite *KeeperTestSuite) TestConnOpenTry() {
189156
// retrieve client state of chainA to pass as counterpartyClient
190157
counterpartyClient = suite.chainA.GetClientState(path.EndpointA.ClientID)
191158
}, false},
192-
{"client state verification failed", func() {
193-
err := path.EndpointA.ConnOpenInit()
194-
suite.Require().NoError(err)
195-
196-
// retrieve client state of chainA to pass as counterpartyClient
197-
counterpartyClient = suite.chainA.GetClientState(path.EndpointA.ClientID)
198-
199-
// modify counterparty client without setting in store so it still passes validate but fails proof verification
200-
tmClient, ok := counterpartyClient.(*ibctm.ClientState)
201-
suite.Require().True(ok)
202-
tmClient.LatestHeight = tmClient.LatestHeight.Increment().(clienttypes.Height)
203-
}, false},
204-
{"consensus state verification failed", func() {
205-
// retrieve client state of chainA to pass as counterpartyClient
206-
counterpartyClient = suite.chainA.GetClientState(path.EndpointA.ClientID)
207-
208-
// give chainA wrong consensus state for chainB
209-
consState, found := suite.chainA.App.GetIBCKeeper().ClientKeeper.GetLatestClientConsensusState(suite.chainA.GetContext(), path.EndpointA.ClientID)
210-
suite.Require().True(found)
211-
212-
tmConsState, ok := consState.(*ibctm.ConsensusState)
213-
suite.Require().True(ok)
214-
215-
tmConsState.Timestamp = time.Now()
216-
suite.chainA.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(suite.chainA.GetContext(), path.EndpointA.ClientID, counterpartyClient.GetLatestHeight(), tmConsState)
217-
218-
err := path.EndpointA.ConnOpenInit()
219-
suite.Require().NoError(err)
220-
}, false},
221159
}
222160

223161
for _, tc := range testCases {
@@ -295,35 +233,6 @@ func (suite *KeeperTestSuite) TestConnOpenAck() {
295233
// retrieve client state of chainB to pass as counterpartyClient
296234
counterpartyClient = suite.chainB.GetClientState(path.EndpointB.ClientID)
297235
}, true},
298-
{"invalid counterparty client", func() {
299-
err := path.EndpointA.ConnOpenInit()
300-
suite.Require().NoError(err)
301-
302-
err = path.EndpointB.ConnOpenTry()
303-
suite.Require().NoError(err)
304-
305-
// retrieve client state of chainB to pass as counterpartyClient
306-
counterpartyClient = suite.chainB.GetClientState(path.EndpointB.ClientID)
307-
308-
// Set an invalid client of chainA on chainB
309-
tmClient, ok := counterpartyClient.(*ibctm.ClientState)
310-
suite.Require().True(ok)
311-
tmClient.ChainId = "wrongchainid"
312-
313-
suite.chainB.App.GetIBCKeeper().ClientKeeper.SetClientState(suite.chainB.GetContext(), path.EndpointB.ClientID, tmClient)
314-
}, false},
315-
{"consensus height >= latest height", func() {
316-
err := path.EndpointA.ConnOpenInit()
317-
suite.Require().NoError(err)
318-
319-
// retrieve client state of chainB to pass as counterpartyClient
320-
counterpartyClient = suite.chainB.GetClientState(path.EndpointB.ClientID)
321-
322-
err = path.EndpointB.ConnOpenTry()
323-
suite.Require().NoError(err)
324-
325-
consensusHeight = clienttypes.GetSelfHeight(suite.chainA.GetContext())
326-
}, false},
327236
{"connection not found", func() {
328237
// connections are never created
329238

@@ -334,9 +243,6 @@ func (suite *KeeperTestSuite) TestConnOpenAck() {
334243
err := path.EndpointA.ConnOpenInit()
335244
suite.Require().NoError(err)
336245

337-
// retrieve client state of chainB to pass as counterpartyClient
338-
counterpartyClient = suite.chainB.GetClientState(path.EndpointB.ClientID)
339-
340246
err = path.EndpointB.ConnOpenTry()
341247
suite.Require().NoError(err)
342248

@@ -345,6 +251,7 @@ func (suite *KeeperTestSuite) TestConnOpenAck() {
345251
suite.Require().True(found)
346252

347253
connection.Counterparty.ConnectionId = "badconnectionid"
254+
path.EndpointB.ConnectionID = "badconnectionid"
348255

349256
suite.chainA.App.GetIBCKeeper().ConnectionKeeper.SetConnection(suite.chainA.GetContext(), path.EndpointA.ConnectionID, connection)
350257

@@ -418,18 +325,6 @@ func (suite *KeeperTestSuite) TestConnOpenAck() {
418325

419326
version = types.NewVersion(types.DefaultIBCVersionIdentifier, []string{"ORDER_ORDERED", "ORDER_UNORDERED", "ORDER_DAG"})
420327
}, false},
421-
{"self consensus state not found", func() {
422-
err := path.EndpointA.ConnOpenInit()
423-
suite.Require().NoError(err)
424-
425-
// retrieve client state of chainB to pass as counterpartyClient
426-
counterpartyClient = suite.chainB.GetClientState(path.EndpointB.ClientID)
427-
428-
err = path.EndpointB.ConnOpenTry()
429-
suite.Require().NoError(err)
430-
431-
consensusHeight = clienttypes.NewHeight(0, 1)
432-
}, false},
433328
{"connection state verification failed", func() {
434329
// chainB connection is not in INIT
435330
err := path.EndpointA.ConnOpenInit()
@@ -438,41 +333,6 @@ func (suite *KeeperTestSuite) TestConnOpenAck() {
438333
// retrieve client state of chainB to pass as counterpartyClient
439334
counterpartyClient = suite.chainB.GetClientState(path.EndpointB.ClientID)
440335
}, false},
441-
{"client state verification failed", func() {
442-
err := path.EndpointA.ConnOpenInit()
443-
suite.Require().NoError(err)
444-
445-
// retrieve client state of chainB to pass as counterpartyClient
446-
counterpartyClient = suite.chainB.GetClientState(path.EndpointB.ClientID)
447-
448-
// modify counterparty client without setting in store so it still passes validate but fails proof verification
449-
tmClient, ok := counterpartyClient.(*ibctm.ClientState)
450-
suite.Require().True(ok)
451-
tmClient.LatestHeight = tmClient.LatestHeight.Increment().(clienttypes.Height)
452-
453-
err = path.EndpointB.ConnOpenTry()
454-
suite.Require().NoError(err)
455-
}, false},
456-
{"consensus state verification failed", func() {
457-
err := path.EndpointA.ConnOpenInit()
458-
suite.Require().NoError(err)
459-
460-
// retrieve client state of chainB to pass as counterpartyClient
461-
counterpartyClient = suite.chainB.GetClientState(path.EndpointB.ClientID)
462-
463-
// give chainB wrong consensus state for chainA
464-
consState, found := suite.chainB.App.GetIBCKeeper().ClientKeeper.GetLatestClientConsensusState(suite.chainB.GetContext(), path.EndpointB.ClientID)
465-
suite.Require().True(found)
466-
467-
tmConsState, ok := consState.(*ibctm.ConsensusState)
468-
suite.Require().True(ok)
469-
470-
tmConsState.Timestamp = tmConsState.Timestamp.Add(time.Second)
471-
suite.chainB.App.GetIBCKeeper().ClientKeeper.SetClientConsensusState(suite.chainB.GetContext(), path.EndpointB.ClientID, counterpartyClient.GetLatestHeight(), tmConsState)
472-
473-
err = path.EndpointB.ConnOpenTry()
474-
suite.Require().NoError(err)
475-
}, false},
476336
}
477337

478338
for _, tc := range testCases {

0 commit comments

Comments
 (0)