You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add upgrade sequences to avoid proof collisions (#724)
* add sequences to error path
* add sequence verification for all handshake methods to ensure only relevant counterparty state is used
* simplify sequence logic
* address pr comments
* increment seq on error
* fix timeout logic
Copy file name to clipboardexpand all lines: spec/core/ics-004-channel-and-packet-semantics/UPGRADES.md
+131-18
Original file line number
Diff line number
Diff line change
@@ -75,8 +75,46 @@ interface UpgradeTimeout {
75
75
76
76
At least one of the timeoutHeight or timeoutTimestamp MUST be non-zero.
77
77
78
+
```typescript
79
+
interfaceErrorReceipt {
80
+
sequence:uint64
81
+
errorMsg:string
82
+
}
83
+
```
84
+
85
+
-`sequence`: Sequence contains the sequence at which the error occurred. Both chains are expected to increment to the next sequence after the upgrade is aborted.
86
+
-`errorMsg`: ErrorMsg contains an arbitrary string which chains may use to provide additional information as to why the upgrade was aborted.
87
+
78
88
### Store Paths
79
89
90
+
#### UpgradeSequencePath
91
+
92
+
The upgrade sequence path is a public path that stores the current sequence of the upgrade attempt. The sequence will increment with each attempted upgrade on the given channel. The sequence will be used to ensure that different error receipts referring to different upgrade attempts do not interfere with each other.
93
+
94
+
```typescript
95
+
function upgradeSequencePath(portIdentifier:Identifier, channelIdentifier:Identifier) Path {
The upgrade sequence MUST also have a verification method so that chains can prove the upgrade sequence on the counterparty for the given channel upgrade.
The chain must store the previous channel end so that it may restore it if the upgrade handshake fails. This may be stored in the private store.
@@ -89,16 +127,15 @@ function restorePath(portIdentifier: Identifier, channelIdentifier: Identifier):
89
127
90
128
#### UpgradeError Path
91
129
92
-
The upgrade error path is a public path that can signal an error of the upgrade to the counterparty. It does not store anything in the successful case, but it will store a sentinel abort value in the case that a chain does not accept the proposed upgrade.
130
+
The upgrade error path is a public path that can signal an error of the upgrade to the counterparty for the given upgrade attempt. It does not store anything in the successful case, but it will store the `ErrorReceipt` in the case that a chain does not accept the proposed upgrade.
93
131
94
132
```typescript
95
133
function errorPath(portIdentifier:Identifier, channelIdentifier:Identifier):Path {
The UpgradeError MUST have an associated verification membership and nonmembership function added to the connection interface so that a counterparty may verify that chain has stored an error in the UpgradeError path.
138
+
The UpgradeError MUST have an associated verification membership and nonmembership function added to the connection interface so that a counterparty may verify that chain has stored a non-empty error in the UpgradeError path.
102
139
103
140
```typescript
104
141
// Connection VerifyChannelUpgradeError method
@@ -108,7 +145,7 @@ function verifyChannelUpgradeError(
@@ -209,11 +254,11 @@ At the end of an upgrade handshake between two chains implementing the sub-proto
209
254
- Each chain is running their new upgraded channel end and is processing upgraded logic and state according to the upgraded parameters.
210
255
- Each chain has knowledge of and has agreed to the counterparty's upgraded channel parameters.
211
256
212
-
If a chain does not agree to the proposed counterparty `UpgradedChannel`, it may abort the upgrade handshake by writing an error receipt into the `errorPath` and restoring the original channel. The error receipt MAY be arbitrary bytes and MUST be non-empty.
257
+
If a chain does not agree to the proposed counterparty `UpgradedChannel`, it may abort the upgrade handshake by writing an ErrorReceipt into the `errorPath` and restoring the original channel. The ErrorReceipt must contain the current upgrade sequence on the erroring chain's channel end.
A relayer may then submit a `ChanUpgradeCancelMsg` to the counterparty. Upon receiving this message a chain must verify that the counterparty wrote a non-empty error receipt into its `UpgradeError`and if successful, it will restore its original channel as well thus cancelling the upgrade.
261
+
A relayer may then submit a `ChanUpgradeCancelMsg` to the counterparty. Upon receiving this message a chain must verify that the counterparty wrote an ErrorReceipt into its `UpgradeError`with a sequence greater than or equal to its own channelEnd's upgrade sequence. If successful, it will restore its original channel as well thus cancelling the upgrade.
217
262
218
263
If an upgrade message arrives after the specified timeout, then the message MUST NOT execute successfully. Again a relayer may submit a proof of this in a `ChanUpgradeTimeoutMsg` so that counterparty cancels the upgrade and restores it original channel as well.
// we must restore the channel since the timeout verification has passed
@@ -605,6 +716,8 @@ function timeoutChannelUpgrade(
605
716
606
717
Note that the timeout logic only applies to the INIT step. This is to protect an upgrading chain from being stuck in a non-OPEN state if the counterparty cannot execute the TRY successfully. Once the TRY step succeeds, then both sides are guaranteed to have the upgrade feature enabled. Liveness is no longer an issue, because we can wait until liveness is restored to execute the ACK step which will move the channel definitely into an OPEN state (either a successful upgrade or a rollback).
607
718
719
+
The error receipt on the counterparty may be empty (either because an upgrade error did not occur in the past, or a previous attempt was pruned), or it may have an outdated sequence (in this case the counterparty errored, our side executed a `CancelUpgrade`, and then subsequently executed `INIT`). In the case where the error receipt is empty, the relayer is expected to submit an absence proof in the timeout message. In the case where the error receipt is for an outdated sequence, the relayer is expected to submit an existence proof in the timeout message. In this case, the handler will assert that the counterparty sequence is outdated **and** the upgrade timeout has passed on the counterparty by the proof height; thus proving that the counterparty did not receive a timeout message within the valid window.
720
+
608
721
The TRY chain will receive the timeout parameters chosen by the counterparty on INIT, so that it can reject any TRY message that is received after the specified timeout. This prevents the handshake from entering into an invalid state, in which the INIT chain processes a timeout successfully and restores its channel to `OPEN` while the TRY chain at a later point successfully writes a `TRY` state.
0 commit comments