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

ICS3: Add Connection Upgrade Spec #621

Merged
merged 29 commits into from
Mar 22, 2022
Merged

ICS3: Add Connection Upgrade Spec #621

merged 29 commits into from
Mar 22, 2022

Conversation

AdityaSripal
Copy link
Member

This is a rough draft proposal for the ability to upgrade a connection once it has already been established

@AdityaSripal
Copy link
Member Author

Some notes:

  • Current idea is that upgrading a connection will require bilateral agreement. i.e. Both sides must explicitly allow the initial parts of handshake (INIT and TRY). Ack and Confirm can be completed by trustless relayer.
  • There is currently a timeout specified on INIT and TRY, so that the connection does not hang indefinitely in a closed state. Not fully specified yet.
  • The details of how to handle crossing hellos is not fully specified yet, so ignore that possibility on initial review.

Copy link
Contributor

@colin-axner colin-axner left a comment

Choose a reason for hiding this comment

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

Excellent!! Concept makes sense to me. Architecturally not difficult to introduce into existing ibc implementations

spec/core/ics-003-connection-semantics/UPGRADES.md Outdated Show resolved Hide resolved
spec/core/ics-003-connection-semantics/UPGRADES.md Outdated Show resolved Hide resolved
}

provableStore.set(statusPath(identifier), upgradeStatus)
provableStore.set(connectionPath(identifier), proposedUpgrade.connection)
Copy link
Contributor

Choose a reason for hiding this comment

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

Interesting, I'd think you'd want to leave the connection unchanged until the upgrade process successfully completes. Otherwise you could potentially disrupt packet flow if the connection is in UPGRADE_INIT instead of OPEN?

I'd expect you to store the proposed upgrade connection under a proposed upgrade connection path. Use that for proofs and then if successful update the connection on ack/confirm?

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't want the case where chainA has its connectionEnd OPEN with the old parameters, and chainB has its connectionEnd OPEN with the new parameters as that may cause unexpected consequences.

If a connection is OPEN on both ends it should be a valid connection always.

So either both ends are OPEN running the old parameters, or both ends are OPEN running the new parameters.

The only way to accomplish this is to temporarily close the connection on both sides (INIT and TRY), then reopen after the upgrade is complete on either end (ACK and CONFIRM).

This does mean packet flow is temporarily halted but i believe this is fine. Once the connection is back up, the relayers can either receive or timeout the pending packets

Copy link
Member Author

Choose a reason for hiding this comment

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

This is also why I specify a timeout, because I don't want the "temporary pause" to last arbitrarily long

Copy link
Contributor

Choose a reason for hiding this comment

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

yeah, this makes sense to me

Copy link
Contributor

@cwgoes cwgoes left a comment

Choose a reason for hiding this comment

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

Concept ACK; most changes ACK (modulo open question of crossing hellos); see a few minor comments.

I will also note that I would like to see re-verification of IBC safety / liveness with this logic incorporated.

spec/core/ics-003-connection-semantics/UPGRADES.md Outdated Show resolved Hide resolved
spec/core/ics-003-connection-semantics/UPGRADES.md Outdated Show resolved Hide resolved
spec/core/ics-003-connection-semantics/UPGRADES.md Outdated Show resolved Hide resolved
}

provableStore.set(statusPath(identifier), upgradeStatus)
provableStore.set(connectionPath(identifier), proposedUpgrade.connection)
Copy link
Contributor

Choose a reason for hiding this comment

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

yeah, this makes sense to me

spec/core/ics-003-connection-semantics/UPGRADES.md Outdated Show resolved Hide resolved
Co-authored-by: Christopher Goes <cwgoes@pluranimity.org>
@AdityaSripal AdityaSripal marked this pull request as draft December 6, 2021 10:06
@AdityaSripal AdityaSripal marked this pull request as ready for review February 11, 2022 14:54
Copy link
Contributor

@mpoke mpoke left a comment

Choose a reason for hiding this comment

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

Concept ACK. I agree with Christopher that we need to make sure that the IBC safety and liveness are preserved with this logic incorporated. See comments below.

spec/core/ics-003-connection-semantics/UPGRADES.md Outdated Show resolved Hide resolved
spec/core/ics-003-connection-semantics/UPGRADES.md Outdated Show resolved Hide resolved
spec/core/ics-003-connection-semantics/UPGRADES.md Outdated Show resolved Hide resolved
spec/core/ics-003-connection-semantics/UPGRADES.md Outdated Show resolved Hide resolved
spec/core/ics-003-connection-semantics/UPGRADES.md Outdated Show resolved Hide resolved
spec/core/ics-003-connection-semantics/UPGRADES.md Outdated Show resolved Hide resolved
spec/core/ics-003-connection-semantics/UPGRADES.md Outdated Show resolved Hide resolved
spec/core/ics-003-connection-semantics/UPGRADES.md Outdated Show resolved Hide resolved
spec/core/ics-003-connection-semantics/UPGRADES.md Outdated Show resolved Hide resolved
@AdityaSripal AdityaSripal requested a review from mpoke March 2, 2022 16:59
@AdityaSripal AdityaSripal changed the title Add Connection Upgrade Spec ICS3: Add Connection Upgrade Spec Mar 7, 2022

```typescript
// Client VerifyUpgradeError
function verifyConnectionUpgradeError(
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
function verifyConnectionUpgradeError(
function VerifyUpgradeError(

Copy link
Member Author

Choose a reason for hiding this comment

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

I've added Connection here to the name because there are identical functions for channel upgradability.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, but the comment above is // Client VerifyUpgradeError and in the above function, i.e.,

// Connection VerifyConnectionUpgradeError method
 function verifyConnectionUpgradeError(

you call client.verifyUpgradeError


```typescript
// Client VerifyUpgradeTimeout
function verifyConnectionUpgradeTimeout(
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
function verifyConnectionUpgradeTimeout(
function VerifyUpgradeTimeout(

Copy link
Member Author

Choose a reason for hiding this comment

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

ditto

spec/core/ics-003-connection-semantics/UPGRADES.md Outdated Show resolved Hide resolved
spec/core/ics-003-connection-semantics/UPGRADES.md Outdated Show resolved Hide resolved
```typescript
// Client VerifyUpgradeError
function verifyConnectionUpgradeError(
clientState: ClientState,
Copy link
Contributor

Choose a reason for hiding this comment

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

clientState is not passed when calling client.verifyUpgradeError()

Copy link
Member Author

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, I've seen that. I find it very confusing. Until now I thought it's an inconsistency. Still not convinced that it's not :)

```typescript
// Client VerifyUpgradeTimeout
function verifyConnectionUpgradeTimeout(
clientState: ClientState,
Copy link
Contributor

Choose a reason for hiding this comment

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

clientState is not passed when calling client.verifyUpgradeTimeout()

Copy link
Member Author

Choose a reason for hiding this comment

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

ditto

Comment on lines 171 to 174
path = applyPrefix(prefix, timeoutPath(counterpartyConnectionIdentifier))
abortTransactionUnless(!clientState.frozen)
timeoutBytes = protobuf.marshal(upgradeTimeout)
return clientState.verifiedRoots[height].verifyMembership(path, timeoutBytes, proof)
Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

This does not assume anything about Tendermint, but just says we will verify membership against a consensus state at provided height. This is taken from ICS2.

https://github.com/cosmos/ibc/blob/master/spec/core/ics-002-client-semantics/README.md#example-implementation

spec/core/ics-003-connection-semantics/UPGRADES.md Outdated Show resolved Hide resolved
spec/core/ics-003-connection-semantics/UPGRADES.md Outdated Show resolved Hide resolved
spec/core/ics-003-connection-semantics/UPGRADES.md Outdated Show resolved Hide resolved
spec/core/ics-003-connection-semantics/UPGRADES.md Outdated Show resolved Hide resolved
Copy link
Contributor

@mpoke mpoke left a comment

Choose a reason for hiding this comment

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

Thanks for the changes. The protocol seems correct. I left some comments, most of them minor.

spec/core/ics-003-connection-semantics/UPGRADES.md Outdated Show resolved Hide resolved
spec/core/ics-003-connection-semantics/UPGRADES.md Outdated Show resolved Hide resolved
spec/core/ics-003-connection-semantics/UPGRADES.md Outdated Show resolved Hide resolved
spec/core/ics-003-connection-semantics/UPGRADES.md Outdated Show resolved Hide resolved
@AdityaSripal AdityaSripal requested a review from mpoke March 9, 2022 15:09
Copy link
Contributor

@colin-axner colin-axner left a comment

Choose a reason for hiding this comment

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

Only reviewed up to the Sub-Protocols section. LGTM so far

spec/core/ics-003-connection-semantics/UPGRADES.md Outdated Show resolved Hide resolved
spec/core/ics-003-connection-semantics/UPGRADES.md Outdated Show resolved Hide resolved
Comment on lines +356 to +359
if counterpartyConnection.State != UPGRADE_TRY {
restoreConnection()
return
}
Copy link
Contributor

Choose a reason for hiding this comment

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

we have to be careful to not use relayer provided information unless verified (especially if we are restoring/cancelling an upgrade)

Copy link
Contributor

@mpoke mpoke left a comment

Choose a reason for hiding this comment

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

Looks great. I have just one concern regarding the transition from UPGRADE_TRY to OPEN (i.e., connUpgradeConfirm). The rest of the comments are just nits.

spec/core/ics-003-connection-semantics/UPGRADES.md Outdated Show resolved Hide resolved
spec/core/ics-003-connection-semantics/UPGRADES.md Outdated Show resolved Hide resolved
}
```

The UpgradeError MUST have an associated verification function added to the connection and client interfaces so that a counterparty may verify that chain has stored an error in the UpgradeError path.
Copy link
Contributor

Choose a reason for hiding this comment

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

A verification function is no longer needed for the client interface.

}
```

The timeout path MUST have associated verification methods on the connection and client interfaces in order for a counterparty to prove that a chain stored a particular `UpgradeTimeout`.
Copy link
Contributor

Choose a reason for hiding this comment

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

ditto

// construct CommitmentPath
path = applyPrefix(connection.counterpartyPrefix, connectionTimeoutPath(connection.counterpartyConnectionIdentifier))
// marshal upgradeTimeout into bytes with standardized protobuf codec
timeoutBytes = protobuf.marshal(upgradeTimeout)
Copy link
Contributor

Choose a reason for hiding this comment

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

I find this a detail of implementation. Not sure it's needed in the spec.

Copy link
Member Author

Choose a reason for hiding this comment

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

No because both sides must agree on an encoding, otherwise they won't be able to verify correctly. So it must be part of spec. I think this is a downside in the rest of spec, that it doesn't explicitly define the encoding you need to use to speak with other IBC chains

spec/core/ics-003-connection-semantics/UPGRADES.md Outdated Show resolved Hide resolved
restoreConnection()
return
}
upgradeTimeout = UpgradeTimeout{
Copy link
Contributor

Choose a reason for hiding this comment

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

upgradeTimeout is not used.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ahh oops, it gets used above in proof verification. Will reorder


// verify proofs of counterparty state
abortTransactionUnless(verifyConnectionState(currentConnection, proofHeight, proofConnection, currentConnection.counterpartyConnectionIdentifier, counterpartyConnection))

Copy link
Contributor

Choose a reason for hiding this comment

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

Before changing the local connection state to OPEN, shouldn't we check again that the remote connection is compatible with the local one? During connUpgradeAck, the remote side could restore the connection, which means moving to a connection with state OPEN. Just verifying that the remote side is OPEN may not be enough.

connUpgradeConfirm should also contain a proof that UpgradeError was not set by the remote side.

Copy link
Member Author

Choose a reason for hiding this comment

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

Ahh thank you, nice catch

spec/core/ics-003-connection-semantics/UPGRADES.md Outdated Show resolved Hide resolved
spec/core/ics-003-connection-semantics/UPGRADES.md Outdated Show resolved Hide resolved
AdityaSripal and others added 2 commits March 22, 2022 11:58
Co-authored-by: Marius Poke <marius.poke@posteo.de>
@AdityaSripal AdityaSripal merged commit d275905 into master Mar 22, 2022
@AdityaSripal AdityaSripal deleted the aditya/path-upgrade branch March 22, 2022 14:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants