Skip to content

Commit c77912b

Browse files
mergify[bot]colin-axner
authored andcommitted
refactor: remove crossing hellos from 03-connection (backport cosmos#1672) (cosmos#1691)
* refactor: remove crossing hellos from 03-connection (cosmos#1672) * remove crossing hello check from ConnOpenTry and ConnOpenAck * remove unnecessary test cases and fix build * fix tests and add migration docs * fix connection version check in conn open ack * add changelog entry * Update modules/core/03-connection/keeper/handshake.go Co-authored-by: Aditya <[email protected]> * remove unnecessary testing function * improve migration documentation as per review suggestion Co-authored-by: Aditya <[email protected]> (cherry picked from commit 9aab42d) * fix merge conflicts * remove missed merge conflicts * Update docs/migrations/v3-to-v4.md Co-authored-by: colin axnér <[email protected]>
1 parent 9d248bf commit c77912b

File tree

11 files changed

+99
-223
lines changed

11 files changed

+99
-223
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
4343

4444
### API Breaking
4545

46+
* (modules/core/03-connection) [\#1672](https://github.com/cosmos/ibc-go/pull/1672) Remove crossing hellos from connection handshakes. The `PreviousConnectionId` in `MsgConnectionOpenTry` has been deprecated.
4647
* (modules/core/04-channel) [\#1317](https://github.com/cosmos/ibc-go/pull/1317) Remove crossing hellos from channel handshakes. The `PreviousChannelId` in `MsgChannelOpenTry` has been deprecated.
4748
* (transfer) [\#1250](https://github.com/cosmos/ibc-go/pull/1250) Deprecate `GetTransferAccount` since the `transfer` module account is never used.
4849
* (channel) [\#1283](https://github.com/cosmos/ibc-go/pull/1283) The `OnChanOpenInit` application callback now returns a version string in line with the latest [spec changes](https://github.com/cosmos/ibc/pull/629).

docs/ibc/proto-docs.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4244,7 +4244,7 @@ connection on Chain B.
42444244
| Field | Type | Label | Description |
42454245
| ----- | ---- | ----- | ----------- |
42464246
| `client_id` | [string](#string) | | |
4247-
| `previous_connection_id` | [string](#string) | | in the case of crossing hello's, when both chains call OpenInit, we need the connection identifier of the previous connection in state INIT |
4247+
| `previous_connection_id` | [string](#string) | | **Deprecated.** Deprecated: this field is unused. Crossing hellos are no longer supported in core IBC. |
42484248
| `client_state` | [google.protobuf.Any](#google.protobuf.Any) | | |
42494249
| `counterparty` | [Counterparty](#ibc.core.connection.v1.Counterparty) | | |
42504250
| `delay_period` | [uint64](#uint64) | | |

docs/migrations/v3-to-v4.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ No genesis or in-place migrations required when upgrading from v1 or v2 of ibc-g
2222

2323
## IBC Apps
2424

25+
### ICS03 - Connection
26+
27+
Crossing hellos have been removed from 03-connection handshake negotiation.
28+
`PreviousConnectionId` in `MsgConnectionOpenTry` has been deprecated and is no longer used by core IBC.
29+
2530
### ICS04 - Channel
2631

2732
The `WriteAcknowledgement` API now takes the `exported.Acknowledgement` type instead of passing in the acknowledgement byte array directly.
@@ -100,4 +105,4 @@ if err := k.icaControllerKeeper.RegisterInterchainAccount(ctx, msg.ConnectionId,
100105

101106
When using the `DenomTrace` gRPC, the full IBC denomination with the `ibc/` prefix may now be passed in.
102107

103-
Crossing hellos are no longer supported by core IBC. The handshake should be completed in the logical 4 step process (INIT, TRY, ACK, CONFIRM).
108+
Crossing hellos are no longer supported by core IBC for 03-connection and 04-channel. The handshake should be completed in the logical 4 step process (INIT, TRY, ACK, CONFIRM).

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

Lines changed: 13 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
package keeper
22

33
import (
4-
"bytes"
5-
64
"github.com/Finschia/finschia-sdk/telemetry"
75
sdk "github.com/Finschia/finschia-sdk/types"
86
sdkerrors "github.com/Finschia/finschia-sdk/types/errors"
9-
"github.com/gogo/protobuf/proto"
107

118
clienttypes "github.com/cosmos/ibc-go/v4/modules/core/02-client/types"
129
"github.com/cosmos/ibc-go/v4/modules/core/03-connection/types"
@@ -28,7 +25,7 @@ func (k Keeper) ConnOpenInit(
2825
) (string, error) {
2926
versions := types.GetCompatibleVersions()
3027
if version != nil {
31-
if !types.IsSupportedVersion(version) {
28+
if !types.IsSupportedVersion(types.GetCompatibleVersions(), version) {
3229
return "", sdkerrors.Wrap(types.ErrInvalidVersion, "version is not supported")
3330
}
3431

@@ -63,7 +60,6 @@ func (k Keeper) ConnOpenInit(
6360
// - Identifiers are checked on msg validation
6461
func (k Keeper) ConnOpenTry(
6562
ctx sdk.Context,
66-
previousConnectionID string, // previousIdentifier
6763
counterparty types.Counterparty, // counterpartyConnectionIdentifier, counterpartyPrefix and counterpartyClientIdentifier
6864
delayPeriod uint64,
6965
clientID string, // clientID of chainA
@@ -75,44 +71,9 @@ func (k Keeper) ConnOpenTry(
7571
proofHeight exported.Height, // height at which relayer constructs proof of A storing connectionEnd in state
7672
consensusHeight exported.Height, // latest height of chain B which chain A has stored in its chain B client
7773
) (string, error) {
78-
var (
79-
connectionID string
80-
previousConnection types.ConnectionEnd
81-
found bool
82-
)
83-
84-
// empty connection identifier indicates continuing a previous connection handshake
85-
if previousConnectionID != "" {
86-
// ensure that the previous connection exists
87-
previousConnection, found = k.GetConnection(ctx, previousConnectionID)
88-
if !found {
89-
return "", sdkerrors.Wrapf(types.ErrConnectionNotFound, "previous connection does not exist for supplied previous connectionID %s", previousConnectionID)
90-
}
91-
92-
// ensure that the existing connection's
93-
// counterparty is chainA and connection is on INIT stage.
94-
// Check that existing connection versions for initialized connection is equal to compatible
95-
// versions for this chain.
96-
// ensure that existing connection's delay period is the same as desired delay period.
97-
if !(previousConnection.Counterparty.ConnectionId == "" &&
98-
bytes.Equal(previousConnection.Counterparty.Prefix.Bytes(), counterparty.Prefix.Bytes()) &&
99-
previousConnection.ClientId == clientID &&
100-
previousConnection.Counterparty.ClientId == counterparty.ClientId &&
101-
previousConnection.DelayPeriod == delayPeriod) {
102-
return "", sdkerrors.Wrap(types.ErrInvalidConnection, "connection fields mismatch previous connection fields")
103-
}
10474

105-
if !(previousConnection.State == types.INIT) {
106-
return "", sdkerrors.Wrapf(types.ErrInvalidConnectionState, "previous connection state is in state %s, expected INIT", previousConnection.State)
107-
}
108-
109-
// continue with previous connection
110-
connectionID = previousConnectionID
111-
112-
} else {
113-
// generate a new connection
114-
connectionID = k.GenerateConnectionIdentifier(ctx)
115-
}
75+
// generate a new connection
76+
connectionID := k.GenerateConnectionIdentifier(ctx)
11677

11778
selfHeight := clienttypes.GetSelfHeight(ctx)
11879
if consensusHeight.GTE(selfHeight) {
@@ -139,15 +100,10 @@ func (k Keeper) ConnOpenTry(
139100
expectedCounterparty := types.NewCounterparty(clientID, "", commitmenttypes.NewMerklePrefix(prefix.Bytes()))
140101
expectedConnection := types.NewConnectionEnd(types.INIT, counterparty.ClientId, expectedCounterparty, types.ExportedVersionsToProto(counterpartyVersions), delayPeriod)
141102

142-
supportedVersions := types.GetCompatibleVersions()
143-
if len(previousConnection.Versions) != 0 {
144-
supportedVersions = previousConnection.GetVersions()
145-
}
146-
147103
// chain B picks a version from Chain A's available versions that is compatible
148104
// with Chain B's supported IBC versions. PickVersion will select the intersection
149105
// of the supported versions and the counterparty versions.
150-
version, err := types.PickVersion(supportedVersions, counterpartyVersions)
106+
version, err := types.PickVersion(types.GetCompatibleVersions(), counterpartyVersions)
151107
if err != nil {
152108
return "", err
153109
}
@@ -181,7 +137,7 @@ func (k Keeper) ConnOpenTry(
181137
}
182138

183139
k.SetConnection(ctx, connectionID, connection)
184-
k.Logger(ctx).Info("connection state updated", "connection-id", connectionID, "previous-state", previousConnection.State.String(), "new-state", "TRYOPEN")
140+
k.Logger(ctx).Info("connection state updated", "connection-id", connectionID, "previous-state", "NONE", "new-state", "TRYOPEN")
185141

186142
defer func() {
187143
telemetry.IncrCounter(1, "ibc", "connection", "open-try")
@@ -223,28 +179,19 @@ func (k Keeper) ConnOpenAck(
223179
return sdkerrors.Wrap(types.ErrConnectionNotFound, connectionID)
224180
}
225181

226-
// Verify the provided version against the previously set connection state
227-
switch {
228-
// connection on ChainA must be in INIT or TRYOPEN
229-
case connection.State != types.INIT && connection.State != types.TRYOPEN:
230-
return sdkerrors.Wrapf(
231-
types.ErrInvalidConnectionState,
232-
"connection state is not INIT or TRYOPEN (got %s)", connection.State.String(),
233-
)
234-
235-
// if the connection is INIT then the provided version must be supproted
236-
case connection.State == types.INIT && !types.IsSupportedVersion(version):
182+
// verify the previously set connection state
183+
if connection.State != types.INIT {
237184
return sdkerrors.Wrapf(
238185
types.ErrInvalidConnectionState,
239-
"connection state is in INIT but the provided version is not supported %s", version,
186+
"connection state is not INIT (got %s)", connection.State.String(),
240187
)
188+
}
241189

242-
// if the connection is in TRYOPEN then the version must be the only set version in the
243-
// retreived connection state.
244-
case connection.State == types.TRYOPEN && (len(connection.Versions) != 1 || !proto.Equal(connection.Versions[0], version)):
190+
// ensure selected version is supported
191+
if !types.IsSupportedVersion(types.ProtoVersionsToExported(connection.Versions), version) {
245192
return sdkerrors.Wrapf(
246193
types.ErrInvalidConnectionState,
247-
"connection state is in TRYOPEN but the provided version (%s) is not set in the previous connection versions %s", version, connection.Versions,
194+
"the counterparty selected version %s is not supported by versions selected on INIT", version,
248195
)
249196
}
250197

@@ -283,7 +230,7 @@ func (k Keeper) ConnOpenAck(
283230
return err
284231
}
285232

286-
k.Logger(ctx).Info("connection state updated", "connection-id", connectionID, "previous-state", connection.State.String(), "new-state", "OPEN")
233+
k.Logger(ctx).Info("connection state updated", "connection-id", connectionID, "previous-state", "INIT", "new-state", "OPEN")
287234

288235
defer func() {
289236
telemetry.IncrCounter(1, "ibc", "connection", "open-ack")

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

Lines changed: 6 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,11 @@ func (suite *KeeperTestSuite) TestConnOpenInit() {
8080
// connection on chainA is INIT
8181
func (suite *KeeperTestSuite) TestConnOpenTry() {
8282
var (
83-
path *ibctesting.Path
84-
delayPeriod uint64
85-
previousConnectionID string
86-
versions []exported.Version
87-
consensusHeight exported.Height
88-
counterpartyClient exported.ClientState
83+
path *ibctesting.Path
84+
delayPeriod uint64
85+
versions []exported.Version
86+
consensusHeight exported.Height
87+
counterpartyClient exported.ClientState
8988
)
9089

9190
testCases := []struct {
@@ -100,15 +99,6 @@ func (suite *KeeperTestSuite) TestConnOpenTry() {
10099
// retrieve client state of chainA to pass as counterpartyClient
101100
counterpartyClient = suite.chainA.GetClientState(path.EndpointA.ClientID)
102101
}, true},
103-
{"success with crossing hellos", func() {
104-
err := suite.coordinator.ConnOpenInitOnBothChains(path)
105-
suite.Require().NoError(err)
106-
107-
// retrieve client state of chainA to pass as counterpartyClient
108-
counterpartyClient = suite.chainA.GetClientState(path.EndpointA.ClientID)
109-
110-
previousConnectionID = path.EndpointB.ConnectionID
111-
}, true},
112102
{"success with delay period", func() {
113103
err := path.EndpointA.ConnOpenInit()
114104
suite.Require().NoError(err)
@@ -227,8 +217,6 @@ func (suite *KeeperTestSuite) TestConnOpenTry() {
227217

228218
// retrieve client state of chainA to pass as counterpartyClient
229219
counterpartyClient = suite.chainA.GetClientState(path.EndpointA.ClientID)
230-
231-
previousConnectionID = path.EndpointB.ConnectionID
232220
}, false},
233221
{"invalid previous connection has invalid versions", func() {
234222
// open init chainA
@@ -253,8 +241,6 @@ func (suite *KeeperTestSuite) TestConnOpenTry() {
253241

254242
// retrieve client state of chainA to pass as counterpartyClient
255243
counterpartyClient = suite.chainA.GetClientState(path.EndpointA.ClientID)
256-
257-
previousConnectionID = path.EndpointB.ConnectionID
258244
}, false},
259245
}
260246

@@ -265,7 +251,6 @@ func (suite *KeeperTestSuite) TestConnOpenTry() {
265251
suite.SetupTest() // reset
266252
consensusHeight = clienttypes.ZeroHeight() // must be explicitly changed in malleate
267253
versions = types.GetCompatibleVersions() // must be explicitly changed in malleate
268-
previousConnectionID = ""
269254
path = ibctesting.NewPath(suite.chainA, suite.chainB)
270255
suite.coordinator.SetupClients(path)
271256

@@ -292,7 +277,7 @@ func (suite *KeeperTestSuite) TestConnOpenTry() {
292277
proofClient, _ := suite.chainA.QueryProof(clientKey)
293278

294279
connectionID, err := suite.chainB.App.GetIBCKeeper().ConnectionKeeper.ConnOpenTry(
295-
suite.chainB.GetContext(), previousConnectionID, counterparty, delayPeriod, path.EndpointB.ClientID, counterpartyClient,
280+
suite.chainB.GetContext(), counterparty, delayPeriod, path.EndpointB.ClientID, counterpartyClient,
296281
versions, proofInit, proofClient, proofConsensus,
297282
proofHeight, consensusHeight,
298283
)
@@ -333,27 +318,6 @@ func (suite *KeeperTestSuite) TestConnOpenAck() {
333318
// retrieve client state of chainB to pass as counterpartyClient
334319
counterpartyClient = suite.chainB.GetClientState(path.EndpointB.ClientID)
335320
}, true},
336-
{"success from tryopen", func() {
337-
// chainA is in TRYOPEN, chainB is in TRYOPEN
338-
err := path.EndpointB.ConnOpenInit()
339-
suite.Require().NoError(err)
340-
341-
err = path.EndpointA.ConnOpenTry()
342-
suite.Require().NoError(err)
343-
344-
// set chainB to TRYOPEN
345-
connection := path.EndpointB.GetConnection()
346-
connection.State = types.TRYOPEN
347-
connection.Counterparty.ConnectionId = path.EndpointA.ConnectionID
348-
suite.chainB.App.GetIBCKeeper().ConnectionKeeper.SetConnection(suite.chainB.GetContext(), path.EndpointB.ConnectionID, connection)
349-
// update path.EndpointB.ClientID so state change is committed
350-
path.EndpointB.UpdateClient()
351-
352-
path.EndpointA.UpdateClient()
353-
354-
// retrieve client state of chainB to pass as counterpartyClient
355-
counterpartyClient = suite.chainB.GetClientState(path.EndpointB.ClientID)
356-
}, true},
357321
{"invalid counterparty client", func() {
358322
err := path.EndpointA.ConnOpenInit()
359323
suite.Require().NoError(err)
@@ -440,28 +404,6 @@ func (suite *KeeperTestSuite) TestConnOpenAck() {
440404

441405
version = types.NewVersion("2.0", nil)
442406
}, false},
443-
{"connection is in TRYOPEN but the set version in the connection is invalid", func() {
444-
// chainA is in TRYOPEN, chainB is in TRYOPEN
445-
err := path.EndpointB.ConnOpenInit()
446-
suite.Require().NoError(err)
447-
448-
err = path.EndpointA.ConnOpenTry()
449-
suite.Require().NoError(err)
450-
451-
// set chainB to TRYOPEN
452-
connection := path.EndpointB.GetConnection()
453-
connection.State = types.TRYOPEN
454-
suite.chainB.App.GetIBCKeeper().ConnectionKeeper.SetConnection(suite.chainB.GetContext(), path.EndpointB.ConnectionID, connection)
455-
456-
// update path.EndpointB.ClientID so state change is committed
457-
path.EndpointB.UpdateClient()
458-
path.EndpointA.UpdateClient()
459-
460-
// retrieve client state of chainB to pass as counterpartyClient
461-
counterpartyClient = suite.chainB.GetClientState(path.EndpointB.ClientID)
462-
463-
version = types.NewVersion("2.0", nil)
464-
}, false},
465407
{"incompatible IBC versions", func() {
466408
err := path.EndpointA.ConnOpenInit()
467409
suite.Require().NoError(err)

0 commit comments

Comments
 (0)