Open AdityaSripal opened 2 years ago
In order for an upgrade to work, the counterparty must support both the legacy client and the new client implementations.
If I'm reading this correctly, counterparties would need to upgrade first to be able to read the new information. Once counterparties have completed their upgrade, they're able to receive messages that would previously have been breaking. Is that roughly correct?
Additionally, once the client is upgraded, it needs to be able to verify across the breaking point, is that right? Would the proposed migration method be able to upgrade and downgrade to span the new and legacy versions or is it upgrade only? I don't see a reason that verifying across the break should not be possible, but it seems a bit complex. Perhaps this isn't a problem in the IBC context but I'm not certain so I figured I'd raise it.
If I'm reading this correctly, counterparties would need to upgrade first to be able to read the new information. Once counterparties have completed their upgrade, they're able to receive messages that would previously have been breaking. Is that roughly correct?
Correct, counterparties would need both the Upgrade mechanism sketched out here (1 time upgrade) as well as both the legacy and new client implementations (would need to add new client implementations as they come in). This is largely unavoidable.
it needs to be able to verify across the breaking point, is that right
Not sure exactly what you mean by this. The legacy chain will need to commit to the new client. This is already how the current upgrade mechanism works. We're using the same idea to make the upgrades more flexible. The legacy client is not expected to verify a new client's header if that is what you are asking.
Would the proposed migration method be able to upgrade and downgrade to span the new and legacy versions or is it upgrade only?
This depends entirely on the individual client implementations of MigrateClient
.
In order to upgrade, the new client implementation must be able to take in a legacy client and return a new client.
In order to downgrade the legacy client implementation must be able to take in a new client and return a legacy client in MigrateClient
.
From the IBC perspective there's no concept of "upgrade" and "downgrade", it doesn't understand which client is better or newer. It just follows this process.
So long as Y is capable of converting X, you can change your client from X to Y using this method
So long as Y is capable of converting X, you can change your client from X to Y using this method
I see, so then code may need to exist to convert new clients into legacy clients using this mechanism. I'm not incredibly familiar with the IBC upgrade path but I think that the easier thing is to make the clients backwards compatible. In the case of adding BLS signatures, clients would be backwards compatible by being able to parse both old and new signature schemes. Perhaps there are cases where non-backwards compatible breaking changes would be introduced, but for BLS signatures this should not be the case.
Currently the upgrades to tendermint client only support changes to particular fields in the current client state struct.
This is limiting, as future versions of the tendermint protocol may wish to make breaking changes to the light client which may require a new IBC
clientstate
.Currently the upgrade protocol for Tendermint works like such:
ClientState
that its counterparties should upgrade right before it does the upgradeClientState
to all counterparties in aMsgUpgradeClient
ClientState
and the relayer-chosen fields from the currentClientState
.https://github.com/cosmos/ibc-go/blob/main/modules/light-clients/07-tendermint/types/upgrade.go#L101
Note that since there is no change to the binaries themselves, these upgrades will work for all counterparties
We can allow a more permissive upgrade protocol, if we introduce a new function to the ClientState interface:
MigrateClient(exported.ClientState) exported.ClientState
New client implementations can implement this method to take in a legacy client and return the equivalent upgraded clientstate struct. It may also make modifications to the client store to migrate consensus states/metadata for the new implementation. The
MigrateClient
method will decide which legacy clients are supported for migration.So for example, a future BLS Tendermint client (which may involve a new client struct and different VerifyHeader implementation) can implement a method to take in the current Tendermint client and return the equivalent BLS client struct, but will reject migrating a solomachine client.
In order for an upgrade to work, the counterparty must support both the legacy client and the new client implementations. If this is the case, then a chain can upgrade to a new breaking light client like so:
ClientState
that its counterparties should upgrade right before it does the upgrade. Note this may be a completely different implementation to the previous one.ClientState
to all counterparties in aMsgUpgradeClient
newClient = committedClient.MigrateClient(legacyClient)
This proposal has a number of advantages. It is not as restrictive as the current upgrade process. All fields of the clientstate are now subject to being changed appropriately since responsibility is handed to light client implementations. Upgrades to light client breaking versions of consensus are supported. Upgrades to new consensus algorithms are supported (provided the new consensus can provide a secure and correct migration from the old consensus's client)
cc: @colin-axner @williambanfield