From 2a77bf895002447a9c5d4602534154c8ce16ab6f Mon Sep 17 00:00:00 2001 From: Alvarez <140459501+prestoalvarez@users.noreply.github.com> Date: Sat, 23 Aug 2025 19:30:39 +0200 Subject: [PATCH 1/9] Update client-validation-removal.md --- .../ics-003-connection-semantics/client-validation-removal.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/core/ics-003-connection-semantics/client-validation-removal.md b/spec/core/ics-003-connection-semantics/client-validation-removal.md index d1d764cbb..043997227 100644 --- a/spec/core/ics-003-connection-semantics/client-validation-removal.md +++ b/spec/core/ics-003-connection-semantics/client-validation-removal.md @@ -8,7 +8,7 @@ Client validation was initially included in the connection handshake handlers in IBC relies on locally unique identifiers for each chain's client, connection and channel identifiers. Thus, the identifiers, connection struct and channel struct are not unique to a chain. The only thing that uniquely identifies a chain is its consensus. Specifically, the tuple of `(height, chainID, validatorSet)` is unique for an honest chain. This tuple is committed to by the headers a validator set produces. Thus, if a chain A has a client with a consensus state that is committing to a tuple uniquely identifying chain B; then chain B can be sure that the client on chain A is a client of itself. Thus any connection on chain A built on top of that client is meant to connect to chain B. -The IBC connection handshake used this fact to ensure that the connection handshake only completes for the chains that are directly pointing to one another. If a relayer misconfigured the connection handshake by choosing the wrong counterparty client identifer on `ConnOpenInit`, the handshake would fail on `ConnOpenAck` when the counterparty client is proven to not be a valid client of the initializing chain. Thus, misconfigured connection attempts are blocked from completing. When a connection moves to `OPEN`, we can be sure that only the two chains in question are connected to each other. +The IBC connection handshake used this fact to ensure that the connection handshake only completes for the chains that are directly pointing to one another. If a relayer misconfigured the connection handshake by choosing the wrong counterparty client identifier on `ConnOpenInit`, the handshake would fail on `ConnOpenAck` when the counterparty client is proven to not be a valid client of the initializing chain. Thus, misconfigured connection attempts are blocked from completing. When a connection moves to `OPEN`, we can be sure that only the two chains in question are connected to each other. Without this check, it is possible in very unlucky circumstances to have two chains that are validly connected to each other and also have misconfigured third-party chains that believe they are connected to a chain that is not connected back to them. For an example of this situation, see the attached [diagram](./client-validation-removal.png). In this case, the validly connected chains will have communication between them that follows IBC's correctness and integrity properties. However, the chains that are misconfigured may misinterpret messages sent to other chains as messages intended for them. In this case, the only connection ends that are affected are the misconfigured connection ends that do not correlate to a valid connection end on the intended counterparty. In order for this situation to arise, there would need to not only be relayer error, but also a coincidence in identifiers and handshake message timing. Thus, this is an unlikely situation to arise in practice and the only effect is invalid message processing on misconfigured connections and channel ends. @@ -17,7 +17,7 @@ Without this check, it is possible in very unlucky circumstances to have two cha While it is beneficial that misconfigured connection attempts are blocked from completing, the client validation in the connection handshake introduced a lot of problems for the upgradability and flexibility of the protocol. - Not all chains have the ability to introspect their own consensus, specifically their own consensus history which is required to validate a counterparty's previous consensus state. -- Explicit verification of a counterparty client state and consensus state makes adding new implementions of the same consensus difficult since the validation of any new client implementations must be supported on the counterparty you want to use it with. Thus, the structure of `ClientState` and `ConsensusState` is very difficult to change without interchain coordination. +- Explicit verification of a counterparty client state and consensus state makes adding new implementations of the same consensus difficult since the validation of any new client implementations must be supported on the counterparty you want to use it with. Thus, the structure of `ClientState` and `ConsensusState` is very difficult to change without interchain coordination. - Similarly, the proofs rely on ICS24 paths for the `ClientState` and `ConsensusState`. Thus, changing the key paths to a more efficient representation is very difficult without interchain coordination. ## Social Consensus From 66cdd27be7c92435e5eaffa459bbe87c2ac05c7e Mon Sep 17 00:00:00 2001 From: Alvarez <140459501+prestoalvarez@users.noreply.github.com> Date: Sat, 23 Aug 2025 19:31:00 +0200 Subject: [PATCH 2/9] Update README.md --- spec/app/ics-721-nft-transfer/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/app/ics-721-nft-transfer/README.md b/spec/app/ics-721-nft-transfer/README.md index 299390823..e4a24b08d 100644 --- a/spec/app/ics-721-nft-transfer/README.md +++ b/spec/app/ics-721-nft-transfer/README.md @@ -10,7 +10,7 @@ created: 2021-11-10 modified: 2022-12-15 --- -> This standard document follows the same design principles of [ICS 20](../ics-020-fungible-token-transfer) and inherits most of its content therefrom, while replacing `bank` module based asset tracking logic with that of the `nft` module. +> This standard document follows the same design principles of [ICS 20](../ics-020-fungible-token-transfer) and inherits most of its content there from, while replacing `bank` module based asset tracking logic with that of the `nft` module. ## Synopsis From b8f160627ab0634078c4291b77c3a5b53e2c5027 Mon Sep 17 00:00:00 2001 From: Alvarez <140459501+prestoalvarez@users.noreply.github.com> Date: Sat, 23 Aug 2025 19:31:27 +0200 Subject: [PATCH 3/9] Update README.md --- spec/app/ics-020-fungible-token-transfer/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/app/ics-020-fungible-token-transfer/README.md b/spec/app/ics-020-fungible-token-transfer/README.md index 963896d17..29e34fbb0 100644 --- a/spec/app/ics-020-fungible-token-transfer/README.md +++ b/spec/app/ics-020-fungible-token-transfer/README.md @@ -69,7 +69,7 @@ sequenceDiagram Note over chain A,chain C: C is source zone: C -> A chain C->>chain C: Lock (escrow) vouchers ("transfer/ChannelToB/transfer/ChannelToA/denom") chain C->>chain A: Send transfer packet with vouchers ("transfer/ChannelToB/transfer/ChannelToA/denom") - chain A->>chain A: Mint vouchers ("tansfer/ChannelToC/transfer/ChannelToB/transfer/ChannelToA/denom") + chain A->>chain A: Mint vouchers ("transfer/ChannelToC/transfer/ChannelToB/transfer/ChannelToA/denom") Note over chain A,chain C: A is sink zone: A -> C chain A->>chain A: Burn vouchers ("transfer/ChannelToC/transfer/ChannelToB/transfer/ChannelToA/denom") chain A->>chain C: Send transfer packet with vouchers ("transfer/ChannelToC/transfer/ChannelToB/transfer/ChannelToA/denom") From f389b19152a72c483bccf387b5980add37c7e98a Mon Sep 17 00:00:00 2001 From: Alvarez <140459501+prestoalvarez@users.noreply.github.com> Date: Sat, 23 Aug 2025 19:32:25 +0200 Subject: [PATCH 4/9] Update README.md --- .../ics-020-fungible-token-transfer/deprecated/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/app/ics-020-fungible-token-transfer/deprecated/README.md b/spec/app/ics-020-fungible-token-transfer/deprecated/README.md index 257bb3721..e12f503c0 100644 --- a/spec/app/ics-020-fungible-token-transfer/deprecated/README.md +++ b/spec/app/ics-020-fungible-token-transfer/deprecated/README.md @@ -100,7 +100,7 @@ sequenceDiagram Note over chain A,chain C: C is source zone: C -> A chain C->>chain C: Lock (escrow) vouchers ("transfer/ChannelToB/transfer/ChannelToA/denom") chain C->>chain A: Send transfer packet with vouchers ("transfer/ChannelToB/transfer/ChannelToA/denom") - chain A->>chain A: Mint vouchers ("tansfer/ChannelToC/transfer/ChannelToB/transfer/ChannelToA/denom") + chain A->>chain A: Mint vouchers ("transfer/ChannelToC/transfer/ChannelToB/transfer/ChannelToA/denom") Note over chain A,chain C: A is sink zone: A -> C chain A->>chain A: Burn vouchers ("transfer/ChannelToC/transfer/ChannelToB/transfer/ChannelToA/denom") chain A->>chain C: Send transfer packet with vouchers ("transfer/ChannelToC/transfer/ChannelToB/transfer/ChannelToA/denom") @@ -603,7 +603,7 @@ function onAcknowledgePacket( } else { // the forwarded packet has failed, thus the funds have been refunded to the forwarding address. // we must revert the changes that came from successfully receiving the tokens on our chain - // before propogating the error acknowledgement back to original sender chain + // before propagating the error acknowledgement back to original sender chain revertInFlightChanges(packet, prevPacket) // write error acknowledgement FungibleTokenPacketAcknowledgement ack = FungibleTokenPacketAcknowledgement{false, "forwarded packet failed"} @@ -635,7 +635,7 @@ function onTimeoutPacket(packet: Packet) { if prevPacket != nil { // the forwarded packet has failed, thus the funds have been refunded to the forwarding address. // we must revert the changes that came from successfully receiving the tokens on our chain - // before propogating the error acknowledgement back to original sender chain + // before propagating the error acknowledgement back to original sender chain revertInFlightChanges(packet, prevPacket) // write error acknowledgement FungibleTokenPacketAcknowledgement ack = FungibleTokenPacketAcknowledgement{false, "forwarded packet timed out"} From 407c6718ebb5534357ea74ca01855a34b2673873 Mon Sep 17 00:00:00 2001 From: Alvarez <140459501+prestoalvarez@users.noreply.github.com> Date: Sat, 23 Aug 2025 19:33:06 +0200 Subject: [PATCH 5/9] Update PACKET.md --- spec/IBC_V2/core/ics-004-packet-semantics/PACKET.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/IBC_V2/core/ics-004-packet-semantics/PACKET.md b/spec/IBC_V2/core/ics-004-packet-semantics/PACKET.md index 6a0a2f3e6..31620c280 100644 --- a/spec/IBC_V2/core/ics-004-packet-semantics/PACKET.md +++ b/spec/IBC_V2/core/ics-004-packet-semantics/PACKET.md @@ -39,8 +39,8 @@ interface Payload { version: string, // encoding allows the sending application to specify which // encoding was used to encode the app data - // the receiving applicaton will decode the appData into - // the strucure expected given the version provided + // the receiving application will decode the appData into + // the structure expected given the version provided // if the encoding is not supported, receiving application // must be rejected with an error acknowledgement. // the encoding string MUST be in MIME format @@ -60,7 +60,7 @@ In version 2 of the IBC specification, implementations **MAY** support multiple Each payload will include its own `Encoding` and `AppVersion` that will be sent to the application to instruct it how to decode and interpret the opaque application data. The application must be able to support the provided `Encoding` and `AppVersion` in order to process the `AppData`. If the receiving application does not support the encoding or app version, then the application **must** return an error to IBC core. If the receiving application does support the provided encoding and app version, then the application must decode the application as specified by the `Encoding` string and then process the application as expected by the counterparty given the agreed-upon app version. Since the `Encoding` and `AppVersion` are now in each packet they can be changed on a per-packet basis and an application can simultaneously support many encodings and app versions from a counterparty. This is in stark contrast to IBC version 1 where the channel prenegotiated the channel version (which implicitly negotiates the encoding as well); so that changing the app version after channel opening is very difficult. -All implementations must commit the packet in the standardized IBC commitment format to satisfy the protocol. In order to do this we must first commit the packet data and timeout. The timeout is encoded in LittleEndian format. The packet data which is a list of payloads is committed to by hashing each individual field of the payload and successively concatenating them together. This ensures a standard unambigious commitment for a given packet. Thus a given packet will always create the exact same commitment by all compliant implementations and two different packets will never create the same commitment by a compliant implementation. This commitment value is then stored under the standardized provable packet commitment key as defined below: +All implementations must commit the packet in the standardized IBC commitment format to satisfy the protocol. In order to do this we must first commit the packet data and timeout. The timeout is encoded in LittleEndian format. The packet data which is a list of payloads is committed to by hashing each individual field of the payload and successively concatenating them together. This ensures a standard unambiguous commitment for a given packet. Thus a given packet will always create the exact same commitment by all compliant implementations and two different packets will never create the same commitment by a compliant implementation. This commitment value is then stored under the standardized provable packet commitment key as defined below: ```typescript func packetCommitmentPath(packet: Packet): bytes { From 27724198bf33a764d939b4b48a369ffe8d3d77f9 Mon Sep 17 00:00:00 2001 From: Alvarez <140459501+prestoalvarez@users.noreply.github.com> Date: Sat, 23 Aug 2025 19:33:53 +0200 Subject: [PATCH 6/9] Update PACKET_HANDLER.md --- .../core/ics-004-packet-semantics/PACKET_HANDLER.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/IBC_V2/core/ics-004-packet-semantics/PACKET_HANDLER.md b/spec/IBC_V2/core/ics-004-packet-semantics/PACKET_HANDLER.md index f82d07541..4a5bfd7c8 100644 --- a/spec/IBC_V2/core/ics-004-packet-semantics/PACKET_HANDLER.md +++ b/spec/IBC_V2/core/ics-004-packet-semantics/PACKET_HANDLER.md @@ -26,7 +26,7 @@ interface Payload { } ``` -The packet is never directly serialised and sent to counterparty chains. Instead a standardized non-malleable committment to the packet data is stored under the standardized unique key for the packet as defined in ICS-24. Thus, implementations MAY make individual choices on the exact packet structure and serialization scheme they use internally so long as they respect the standardized commitment defined by the IBC protocol when writing to the provable store. +The packet is never directly serialised and sent to counterparty chains. Instead a standardized non-malleable commitment to the packet data is stored under the standardized unique key for the packet as defined in ICS-24. Thus, implementations MAY make individual choices on the exact packet structure and serialization scheme they use internally so long as they respect the standardized commitment defined by the IBC protocol when writing to the provable store. Packet Invariants: @@ -87,7 +87,7 @@ interface Packet { } ``` -- Since the packet is committed to with a hash in-state, implementations must provide the packet fields for relayers to reconstruct. This can be emitted in an event system or stored in state as the full packet under an auxilliary key if the implementing platform does not have an event system. +- Since the packet is committed to with a hash in-state, implementations must provide the packet fields for relayers to reconstruct. This can be emitted in an event system or stored in state as the full packet under an auxiliary key if the implementing platform does not have an event system. SendPacket Errorconditions: @@ -147,8 +147,8 @@ WriteAcknowledgement Preconditions: WriteAcknowledgement Postconditions: - The acknowledgement is committed and written to the acknowledgement path as specified in ICS24 -- Since the acknowledgement is being hashed, the full acknowledgement fields should be made available for relayers to reconstruct. This can be emitted in an event system or stored in state as the full packet under an auxilliary key if the implementing platform does not have an event system. -- Implementors SHOULD also emit the full packet again in `WriteAcknowledgement` since the sender chain is only expected to store the packet commitment and not the full packet; relayers are expected to pass the packet back to the sender chain to process the acknowledgement. Thus, in order to support stateless relayers it is helpful to re-emit the packet fields on `WriteAcknowledgement` so the relayer can reconstruct the packet. +- Since the acknowledgement is being hashed, the full acknowledgement fields should be made available for relayers to reconstruct. This can be emitted in an event system or stored in state as the full packet under an auxiliary key if the implementing platform does not have an event system. +- Implementers SHOULD also emit the full packet again in `WriteAcknowledgement` since the sender chain is only expected to store the packet commitment and not the full packet; relayers are expected to pass the packet back to the sender chain to process the acknowledgement. Thus, in order to support stateless relayers it is helpful to re-emit the packet fields on `WriteAcknowledgement` so the relayer can reconstruct the packet. - If the acknowledgement is successful, then all receiving applications must have executed their recvPacket logic and written state - If the acknowledgement is unsuccessful (ie ERROR ACK), any state changes made by the receiving applications MUST all be reverted. This ensure atomic execution of the multi-payload packet. From ae68ed65c56f7fbe15caa51d1420664f536d930f Mon Sep 17 00:00:00 2001 From: Alvarez <140459501+prestoalvarez@users.noreply.github.com> Date: Sat, 23 Aug 2025 19:34:17 +0200 Subject: [PATCH 7/9] Update README.md --- spec/IBC_V2/core/ics-002-client-semantics/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/IBC_V2/core/ics-002-client-semantics/README.md b/spec/IBC_V2/core/ics-002-client-semantics/README.md index aaefd6344..57d18002d 100644 --- a/spec/IBC_V2/core/ics-002-client-semantics/README.md +++ b/spec/IBC_V2/core/ics-002-client-semantics/README.md @@ -334,7 +334,7 @@ logical correctness. #### CreateClient -Calling `createClient` with the client state and initial consensus state creates a new client. The intiator of this client is responsible for setting all of the initial parameters of the `ClientState` and the initial root-of-trust `ConsensusState`. The client implementation is then responsible for executing the light client `ValidityPredicate` against these initial parameters. Thus, once a root-of-trust is instantiated; the light client guarantees to preserve that trust within the confines of the security model as parameterized by the `ClientState`. If a user verifies that a client is a valid client of the counterparty chain once, they can be guaranteed that it will remain a valid client into the future so long as the `MisbehaviourPredicate` is not triggered. If the `MisbehaviourPredicate` is triggered however, this can be submitted as misbehaviour to freeze the IBC light client operations. +Calling `createClient` with the client state and initial consensus state creates a new client. The initiator of this client is responsible for setting all of the initial parameters of the `ClientState` and the initial root-of-trust `ConsensusState`. The client implementation is then responsible for executing the light client `ValidityPredicate` against these initial parameters. Thus, once a root-of-trust is instantiated; the light client guarantees to preserve that trust within the confines of the security model as parameterized by the `ClientState`. If a user verifies that a client is a valid client of the counterparty chain once, they can be guaranteed that it will remain a valid client into the future so long as the `MisbehaviourPredicate` is not triggered. If the `MisbehaviourPredicate` is triggered however, this can be submitted as misbehaviour to freeze the IBC light client operations. CreateClient Inputs: From 3f3eb1f3d12d657479d31fcd478c2a67af3a6294 Mon Sep 17 00:00:00 2001 From: Alvarez <140459501+prestoalvarez@users.noreply.github.com> Date: Sat, 23 Aug 2025 19:34:40 +0200 Subject: [PATCH 8/9] Update README.md --- spec/IBC_V2/core/ics-024-host-requirements/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/IBC_V2/core/ics-024-host-requirements/README.md b/spec/IBC_V2/core/ics-024-host-requirements/README.md index 32a913cc6..3c958b6c8 100644 --- a/spec/IBC_V2/core/ics-024-host-requirements/README.md +++ b/spec/IBC_V2/core/ics-024-host-requirements/README.md @@ -101,7 +101,7 @@ Future paths may be used in future versions of the protocol, so the entire key-s | Packet Receipt | {destClientId}0x2{bigEndianUint64Sequence} | | Acknowledgement Commitment | {destClientId}0x3{bigEndianUint64Sequence} | -IBC V2 only proves commitments related to packet handling, thus the commitments and how to construct them are specifed in [ICS-4](../ics-004-packet-semantics/PACKET.md). +IBC V2 only proves commitments related to packet handling, thus the commitments and how to construct them are specified in [ICS-4](../ics-004-packet-semantics/PACKET.md). As mentioned above, the provable path space controlled by the IBC handler may be prefixed in a global provable key/value store. In this case, the prefix must be appended by the IBC handler before the proof is verified. From ea9312fed6aa1809498cd4733a3792866c06f826 Mon Sep 17 00:00:00 2001 From: Alvarez <140459501+prestoalvarez@users.noreply.github.com> Date: Sat, 23 Aug 2025 19:35:46 +0200 Subject: [PATCH 9/9] Update README.md --- spec/IBC_V2/core/ics-026-application-callbacks/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spec/IBC_V2/core/ics-026-application-callbacks/README.md b/spec/IBC_V2/core/ics-026-application-callbacks/README.md index 04a607c96..841e105be 100644 --- a/spec/IBC_V2/core/ics-026-application-callbacks/README.md +++ b/spec/IBC_V2/core/ics-026-application-callbacks/README.md @@ -77,7 +77,7 @@ NOTE: IBC v2 allows multiple payloads coming from multiple applications to be se #### WriteAcknowledgement -The IBC core handler MAY expose the following function signature to the ICS26 applications registed on the port router, so that the application can write acknowledgements asynchronously. +The IBC core handler MAY expose the following function signature to the ICS26 applications registered on the port router, so that the application can write acknowledgements asynchronously. This is only necessary if the implementation supports processing packets asynchronously. In this case, an application may process the packet asynchronously from when the IBC core handler receives the packet. Thus, the acknowledgement cannot be returned as part of the `OnRecvPacket` callback and must be submitted to the core IBC handler by the ICS26 application at a later time. Thus, we must introduce a new endpoint on the IBC handler for the ICS26 application to call when it is done processing a receive packet and wants to write the acknowledgement. @@ -98,7 +98,7 @@ WriteAcknowledgement Postconditions: - If the acknowledgement is successful, then all receiving applications must have executed their recvPacket logic and written state - If the acknowledgement is unsuccessful (ie ERROR ACK), any state changes made by the receiving applications MUST all be reverted. This ensure atomic execution of the multi-payload packet. -NOTE: In the case that the packet contained multiple payloads, the IBC core handler MUST wait for all applications to return their individual acknowledgements for the packet before commiting the acknowledgment. If ANY application returns the error acknowledgement, then the acknowledgement for the entire packet only contains the `ERROR_SENTINEL_ACKNOWLEDGEMENT`. Otherwise, the acknowledgment is a list containing each applications individual acknowledgment in the same order that their associated payload existed in the packet. +NOTE: In the case that the packet contained multiple payloads, the IBC core handler MUST wait for all applications to return their individual acknowledgements for the packet before committing the acknowledgment. If ANY application returns the error acknowledgement, then the acknowledgement for the entire packet only contains the `ERROR_SENTINEL_ACKNOWLEDGEMENT`. Otherwise, the acknowledgment is a list containing each applications individual acknowledgment in the same order that their associated payload existed in the packet. ### ICS26 Interface Exposed to Core Handler @@ -129,7 +129,7 @@ OnRecvPacket ErrorConditions: - The sending application as identified by `payload.SourcePortId` is not allowed to send a payload to the receiving application - The requested version as identified by `payload.Version` is unsupported - The requested encoding as identified by `payload.Encoding` is unsupported -- An error occured while processing the `payload.Value` after decoding with `payload.Encoding` and processing the payload in the manner expected by `payload.Version`. +- An error occurred while processing the `payload.Value` after decoding with `payload.Encoding` and processing the payload in the manner expected by `payload.Version`. IMPORTANT: If the `OnRecvPacket` callback errors for any reason, the state changes made during the callback MUST be reverted and the IBC core handler MUST write the `SENTINEL_ERROR_ACKNOWLEDGEMENT` for this packet even if other payloads in the packet are received successfully.