Skip to content

Commit

Permalink
Merge pull request #298 from hyperledger-labs/improve-docs
Browse files Browse the repository at this point in the history
Update docs

Signed-off-by: Jun Kimura <[email protected]>
  • Loading branch information
bluele authored Sep 26, 2024
2 parents 5ea3c9e + 666e04b commit b41cdf7
Show file tree
Hide file tree
Showing 4 changed files with 452 additions and 21 deletions.
105 changes: 105 additions & 0 deletions docs/adr/adr-002.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# ADR-002: Channel Upgrade

## Changelog

- 2024-04-16: Initial draft

## Overview

We will implement the Channel Upgrade protocol as defined in ICS-04 Upgrades in ibc-solidity. This will enable IBC Modules (applications) deployed using ibc-solidity to safely upgrade or utilize a new connection without establishing a new channel.

## Motivation

Currently, IBC Modules deployed with ibc-solidity lack a method to safely update channel parameters once established. Specifically, there are cases where an IBC Module might need to update its packet data format, protocol semantics, or safely modify the connection associated with the client that verifies the counterparty chain. ICS-04 Upgrades is a protocol that enables the renegotiation of existing channels to support such upgrades. The protocol is defined in the following document:
[https://github.com/cosmos/ibc/blob/main/spec/core/ics-004-channel-and-packet-semantics/UPGRADES.md](https://github.com/cosmos/ibc/blob/main/spec/core/ics-004-channel-and-packet-semantics/UPGRADES.md)

Here are the Motivation and Desired Properties from the document:

> **Motivation**
> As new functionality is added to IBC, chains may want to take advantage of new channel features without abandoning the accumulated state or the network of existing channels. The proposed upgrade protocol allows chains to renegotiate an existing channel to adopt new features while preserving all existing packet state processed on the channel.
> **Desired Properties**
> - Both chains MUST agree to the renegotiated channel parameters.
> - Channel state and logic on both chains SHOULD either be using the old parameters or the new parameters, but MUST NOT be in an in-between state, e.g., it MUST NOT be possible for an application to run v2 logic, while its counterparty is still running v1 logic.
> - The channel upgrade protocol is atomic, i.e.,
> - either it is unsuccessful and then the channel MUST fall-back to the original channel parameters;
> - or it is successful and then both channel ends MUST adopt the new channel parameters and the applications must process packet data appropriately.
> - Packets sent under the previously negotiated parameters must be processed under the previously negotiated parameters, packets sent under the newly negotiated parameters must be processed under the newly negotiated parameters. Thus, in-flight packets sent before the upgrade handshake is complete will be processed according to the original parameters.
> - The channel upgrade protocol MUST NOT modify the channel identifiers.
## Specification

We will implement the upgrade protocol in ibc-solidity, compliant with [ICS-04 channel and Packet Semantics Upgrades](https://github.com/cosmos/ibc/blob/main/spec/core/ics-004-channel-and-packet-semantics/UPGRADES.md). However, certain functions in ICS-04 are specified as implementation detail. Below, we describe the function specifications for ibc-solidity, including any modifications from ICS-04 or ibc-go.

### New Functions

#### `isAuthorizedUpgrader`

This function corresponds to the same function in the ICS-04 and is implemented in the IBC module.

It determines if the `msg.sender` has the authority to run `ChanUpgradeInit`. In ibc-go this is implemented as a chain parameter (called authority). In ibc-solidity, the IBC module implements this function to allow different accounts to have this authority on a per-module basis.

Note that if a malicious actor obtains this authority, they could upgrade a channel with arbitrary parameters. However, this risk is isolated to the IBC Module utilizing that channel, without affecting other channels or modules.

#### `getUpgradeTimeout`

This function corresponds to the same function in the ICS-04 and is implemented in the IBC module.

It returns the absolute time by which the channel’s state must transition to `FLUSHCOMPLETE`. In ibc-go, this is a chain-wide parameter. In ibc-solidity, it is implemented at the IBC Module level, as upgrade requirements may vary between Modules. Setting a very short timeout could cause the upgrade handshake to abort, but in such cases, the channel will revert to the previous parameters, avoiding any unexpected state transitions or channel closed.

#### `canTransitionToFlushComplete`

This function abstracts the `pendingInflightPackets` function in ICS-04 and `HasInflightPackets` in ibc-go, and is implemented in the IBC Module.

It returns a boolean value indicating whether the upgrading channel can transition from `FLUSHING` to `FLUSHCOMPLETE`.

According to ICS-04, the condition for transition from `FLUSHING` to `FLUSHCOMPLETE` is that there are no in-flight packets. Before transition to `FLUSHCOMPLETE`, the core module will call this function to check whether the transition is possible.

In ibc-go, `HasInflightPackets` checks the existence of in-flight packets by iterating over packet commitments in the store. However, unlike ibc-go, the iterator of the store used to efficiently check the existence of packet commitments cannot be used in EVM. This is particularly problem when upgrading `UNORDERED` channels. In ibc-solidity, if the core module cannot detect in-flight packets during `chanUpgradeAck` and `chanUpgradeConfirm`, it will call this function in the IBC Module. For `ORDERED` channels, the core module will transition to `FLUSHCOMPLETE` if the `nextSequenceSend` and `nextSequenceAck` match.

Note that additional trust assumptions are required when off-chain tools are used to verify the existence of in-flight packets. If `COMPLETE` is allowed while `FLUSHING` is not yet done(i.e., in-flight packets exist), the counterparty will not receive pre-upgrade packets or acknowledgments. This means that he responsibility for maintaining the state consistency of the IBC Module belongs to the IBC Module itself.

### Differences from Spec

We have modified the `openUpgradeHandshake` function added in ICS-04 as follows:

#### Ordering type upgraded to `ORDERED`

Changes:

- Set `nextSequenceRecv` to the counterparty’s `nextSequenceSend`.
- Set `nextSequenceAck` to the module's `nextSequenceSend`.

These changes are required to improve the guarantee of the following desired property:
> - Packets sent under the previously negotiated parameters must be processed under the previously negotiated parameters, packets sent under the newly negotiated parameters must be processed under the newly negotiated parameters. Thus, in-flight packets sent before the upgrade handshake is complete will be processed according to the original parameters.
This ensures full compatibility with ICS-04 when all packets are flushed before the `FLUSHCOMPLETE` transition. However, if the transition occurs without fully flushing the packets, the upgraded channel will not be able to receive or acknowledge packets from the previous channel version.

#### `recvPacket` and `acknowledgePacket` in `UNORDERED` channels

Changes:

- Add `recvStartSequence` and `ackStartSequence`.

When a channel ordering type is upgraded from `ORDERED` to `UNORDERED`, it may receive previously sent packets again since it lacks a record of prior packet receipts. To resolve this, ibc-go introduces `recvStartSequence`, which is updated with the counterparty’s `nextSequenceSend` upon upgrade process completion. ibc-solidity also implements `recvStartSequence` to ensure that only packets with sequences greater than this value are received.

In addition, ibc-solidity adds a sequence called `ackStartSequence`, which is updated by `nextSequenceSend` when an upgrade is successful. This is used to check that the target ack packet sequence is greater than or equal to the value when the ack packet is sent. In ibc-go, it is assumed that all packets have been acknowledged and packet commitments have been cleaned up before the upgrade is complete,

## Rationale

We have given the IBC Module the responsibility for additional parameters, authority design and some state check functions. This allows for flexibility across different IBC Modules in choosing best parameters and implementations. Even if a malicious owner of an IBC Module sets invalid parameters, the risk is isolated to that channel and does not affect others.

## Migration

IBC Module contracts may need to upgrade their logic and state to match a new app version of the upgraded channel. This upgrade must only occur if the upgrade is successful. Such upgrades should be performed in the `onChanUpgradeOpen` function.

If a logic upgrade is required, the IBC Module must be implemented as an Upgradeable Contract. "Proxy pattern" is a well-known method of contract upgrade. For example, before `onChanUpgradeOpen` is called, a new implementation contract is deployed, and the proxy’s implementation contract address is updated in `onChanUpgradeOpen`.

## Security Considerations

The threat posed by invalid parameters introduced during the ICS-04 upgrade process is limited to the affected channels.
In ibc-solidity, even if an upgrade occurs before the flushing of packets is complete, the packets and acknowledgements before the upgrade will never be processed in the new channel and their reception will be skipped. For this reason, it is recommended that you ensure that all packets in transmission are flushed before `canTransitionToFlushComplete` returns `true`. Note that if true is returned when there are inflight packets, the IBC Module may be in a state of inconsistency after the upgrade is completed. Such modules will need to recover state consistency during `onChanUpgradeOpen`.

## Reference Implementation

- [IBCChannelUpgrade.sol](../../contracts/core/04-channel/IIBCChannelUpgrade.sol)
Loading

0 comments on commit b41cdf7

Please sign in to comment.