From 20728b1be56d192899795766a8eef9c4328d8dfe Mon Sep 17 00:00:00 2001 From: Evan <87997759+evanorti@users.noreply.github.com> Date: Fri, 20 Feb 2026 13:42:32 -0500 Subject: [PATCH 01/13] fix links --- cometbft/v0.37/docs/guides/go-built-in.mdx | 2 +- .../v0.37/spec/abci/abci++_client_server.mdx | 3 +- .../docs/app-dev/Indexing-Transactions.mdx | 2 +- cometbft/v0.38/docs/core/RPC.mdx | 2 +- .../v0.38/docs/core/Running-in-production.mdx | 2 +- cometbft/v0.38/docs/core/mempool.mdx | 4 +- .../Creating-a-built-in-application-in-Go.mdx | 2 +- .../v0.38/spec/abci/Client-and-server.mdx | 5 +- cometbft/v0.38/spec/abci/Methods.mdx | 10 ++-- cometbft/v0.38/spec/abci/Outline.mdx | 46 +++++++++---------- .../abci/Requirements-for-the-Application.mdx | 8 ++-- .../Byzantine-Consensus-Algorithm.mdx | 6 +-- cometbft/v0.38/spec/core/Data_structures.mdx | 20 ++++---- .../v0.38/spec/light-client/verification.mdx | 4 +- .../spec/p2p/reactor-api/API-for-Reactors.mdx | 8 ++-- .../interoperability/deployment.mdx | 2 +- .../custom-improvement-proposals.mdx | 3 -- .../smart-contracts/precompiles/overview.mdx | 1 - .../documentation/concepts/accounts.mdx | 2 +- .../custom-improvement-proposals.mdx | 3 -- .../smart-contracts/precompiles/p256.mdx | 1 - .../implementation-guide.mdx | 2 +- .../predeployed-contracts/permit2.mdx | 2 +- .../documentation/concepts/accounts.mdx | 2 +- .../custom-improvement-proposals.mdx | 3 -- .../predeployed-contracts.mdx | 2 +- .../smart-contracts/precompiles/overview.mdx | 1 - .../predeployed-contracts/permit2.mdx | 2 +- hub/v25/hub-tutorials/join-testnet.mdx | 4 +- hub/v25/index.mdx | 5 -- sdk/v0.53/build/tooling/cosmovisor.mdx | 2 +- sdk/v0.53/security/bug-bounty.mdx | 3 +- skip-go/widget/configuration.mdx | 2 +- 33 files changed, 73 insertions(+), 93 deletions(-) diff --git a/cometbft/v0.37/docs/guides/go-built-in.mdx b/cometbft/v0.37/docs/guides/go-built-in.mdx index f45e39cd..c59a1e12 100644 --- a/cometbft/v0.37/docs/guides/go-built-in.mdx +++ b/cometbft/v0.37/docs/guides/go-built-in.mdx @@ -639,7 +639,7 @@ Next, we initialize the Badger database and create an app instance. We use `FilePV`, which is a private validator (i.e. thing which signs consensus messages). Normally, you would use `SignerRemote` to connect to an external -[HSM](https://kb.certus.one/hsm.html). +[HSM](https://pkg.go.dev/github.com/certusone/yubihsm-go). ```go pv := privval.LoadFilePV( diff --git a/cometbft/v0.37/spec/abci/abci++_client_server.mdx b/cometbft/v0.37/spec/abci/abci++_client_server.mdx index 5b340e26..10009a2e 100644 --- a/cometbft/v0.37/spec/abci/abci++_client_server.mdx +++ b/cometbft/v0.37/spec/abci/abci++_client_server.mdx @@ -40,8 +40,7 @@ the `--abci` flag appropriately. See examples, in various stages of maintenance, in [Go](https://github.com/cometbft/cometbft/tree/v0.37.x/abci/server), -[JavaScript](https://github.com/tendermint/js-abci), -[C++](https://github.com/mdyring/cpp-tmsp), and +[JavaScript](https://github.com/tendermint/js-abci), and [Java](https://github.com/jTendermint/jabci). ### In Process diff --git a/cometbft/v0.38/docs/app-dev/Indexing-Transactions.mdx b/cometbft/v0.38/docs/app-dev/Indexing-Transactions.mdx index a08da40c..df524b8a 100644 --- a/cometbft/v0.38/docs/app-dev/Indexing-Transactions.mdx +++ b/cometbft/v0.38/docs/app-dev/Indexing-Transactions.mdx @@ -301,4 +301,4 @@ digit, as well as the following characters: `.` (dot), `-` (dash), `_` ^[\w]+[\.-\w]?$ ``` -[abci-events]: ../spec/abci/abci++_basic_concepts.md#events +[abci-events]: /cometbft/v0.38/spec/abci/abci++_basic_concepts#events diff --git a/cometbft/v0.38/docs/core/RPC.mdx b/cometbft/v0.38/docs/core/RPC.mdx index 9819f61b..f922cda3 100644 --- a/cometbft/v0.38/docs/core/RPC.mdx +++ b/cometbft/v0.38/docs/core/RPC.mdx @@ -47,4 +47,4 @@ cors_allowed_origins = [] max_open_connections = 900 ``` -See the [Configuration](./configuration) page for more details on RPC configuration options. +See the [Configuration](/cometbft/v0.38/docs/core/configuration) page for more details on RPC configuration options. diff --git a/cometbft/v0.38/docs/core/Running-in-production.mdx b/cometbft/v0.38/docs/core/Running-in-production.mdx index 64850eb9..99e659ae 100644 --- a/cometbft/v0.38/docs/core/Running-in-production.mdx +++ b/cometbft/v0.38/docs/core/Running-in-production.mdx @@ -383,7 +383,7 @@ give you a limited number of file descriptors. If you want to accept a greater number of connections, you will need to increase these limits. -[Sysctls to tune the system to be able to open more connections](https://github.com/satori-com/tcpkali/blob/master/doc/tcpkali.man.md#sysctls-to-tune-the-system-to-be-able-to-open-more-connections) +[Sysctls to tune the system to be able to open more connections](https://github.com/satori-com/tcpkali/blob/main/doc/tcpkali.man.md#sysctls-to-tune-the-system-to-be-able-to-open-more-connections) The process file limits must also be increased, e.g. via `ulimit -n 8192`. diff --git a/cometbft/v0.38/docs/core/mempool.mdx b/cometbft/v0.38/docs/core/mempool.mdx index d873b97b..7e1f7c75 100644 --- a/cometbft/v0.38/docs/core/mempool.mdx +++ b/cometbft/v0.38/docs/core/mempool.mdx @@ -98,5 +98,5 @@ The ABCI application becomes responsible for storing, disseminating, and proposing transactions using [`PrepareProposal`][2]. The concrete design is up to the ABCI application developers. -[1]: ../../spec/abci/abci++_methods.md#checktx -[2]: ../../spec/abci/abci++_methods.md#prepareproposal +[1]: /cometbft/v0.38/spec/abci/abci++_methods#checktx +[2]: /cometbft/v0.38/spec/abci/abci++_methods#prepareproposal diff --git a/cometbft/v0.38/docs/guides/Creating-a-built-in-application-in-Go.mdx b/cometbft/v0.38/docs/guides/Creating-a-built-in-application-in-Go.mdx index e041735a..b40811a8 100644 --- a/cometbft/v0.38/docs/guides/Creating-a-built-in-application-in-Go.mdx +++ b/cometbft/v0.38/docs/guides/Creating-a-built-in-application-in-Go.mdx @@ -641,7 +641,7 @@ app := NewKVStoreApplication(db) We use `FilePV`, which is a private validator (i.e., a thing which signs consensus messages). Normally, you would use `SignerRemote` to connect to an external -[HSM](https://kb.certus.one/hsm.html). +[HSM](https://pkg.go.dev/github.com/certusone/yubihsm-go). ```go pv := privval.LoadFilePV( diff --git a/cometbft/v0.38/spec/abci/Client-and-server.mdx b/cometbft/v0.38/spec/abci/Client-and-server.mdx index 0eb94c25..8b40b2c0 100644 --- a/cometbft/v0.38/spec/abci/Client-and-server.mdx +++ b/cometbft/v0.38/spec/abci/Client-and-server.mdx @@ -24,7 +24,7 @@ For more details on protobuf, see the [documentation](https://developers.google. {/* As of v0.36 requests are synchronous. For each of ABCI++'s four connections (see -[Connections](./abci%2B%2B_app_requirements.md)), when CometBFT issues a request to the +[Connections](/cometbft/v0.38/spec/abci/abci++_app_requirements)), when CometBFT issues a request to the Application, it will wait for the response before continuing execution. As a side effect, requests and responses are ordered for each connection, but not necessarily across connections. */} @@ -45,8 +45,7 @@ the `--abci` flag appropriately. See examples, in various stages of maintenance, in [Go](https://github.com/cometbft/cometbft/tree/master/abci/server), -[JavaScript](https://github.com/tendermint/js-abci), -[C++](https://github.com/mdyring/cpp-tmsp), and +[JavaScript](https://github.com/tendermint/js-abci), and [Java](https://github.com/jTendermint/jabci). ### In Process diff --git a/cometbft/v0.38/spec/abci/Methods.mdx b/cometbft/v0.38/spec/abci/Methods.mdx index e1861104..cd06958b 100644 --- a/cometbft/v0.38/spec/abci/Methods.mdx +++ b/cometbft/v0.38/spec/abci/Methods.mdx @@ -310,7 +310,7 @@ title: Methods | height | int64 | The height of the block that will be proposed. | 5 | | time | [google.protobuf.Timestamp][protobuf-timestamp] | Timestamp of the block that that will be proposed. | 6 | | next_validators_hash | bytes | Merkle root of the next validator set. | 7 | - | proposer_address | bytes | [Address](../core/Data_structures.mdx#address) of the validator that is creating the proposal. | 8 | + | proposer_address | bytes | [Address](/cometbft/v0.38/spec/core/Data_structures#address) of the validator that is creating the proposal. | 8 | * **Response**: @@ -531,13 +531,13 @@ then _p_ locks _v_ and sends a Precommit message in the following way and signs the populated data structure. 5. _p_ constructs and signs the [CanonicalVote](/cometbft/v0.38/spec/core/Data_structures#canonicalvote) structure. 6. _p_ constructs the Precommit message (i.e. [Vote](/cometbft/v0.38/spec/core/Data_structures#vote) structure) - using [CanonicalVoteExtension](../core/Data_structures.mdx#canonicalvoteextension) + using [CanonicalVoteExtension](/cometbft/v0.38/spec/core/Data_structures#canonicalvoteextension) and [CanonicalVote](/cometbft/v0.38/spec/core/Data_structures#canonicalvoteextension). 7. _p_ broadcasts the Precommit message. In the cases when _p_ is to broadcast `precommit nil` messages (either _2f+1_ `prevote nil` messages received, or _timeoutPrevote_ triggered), _p_'s CometBFT does **not** call `RequestExtendVote` and will not include -a [CanonicalVoteExtension](../core/Data_structures.mdx#canonicalvoteextension) field in the `precommit nil` message. +a [CanonicalVoteExtension](/cometbft/v0.38/spec/core/Data_structures#canonicalvoteextension) field in the `precommit nil` message. ### VerifyVoteExtension @@ -805,7 +805,7 @@ Most of the data structures used in ABCI are shared [common data structures](/co | Name | Type | Description | Field Number | |---------------|-------------------------------------------------------|------------------------------------------------------------------------------------------|--------------| | validator | [Validator](#validator) | The validator that sent the vote. | 1 | - | block_id_flag | [BlockIDFlag](../core/Data_structures.mdx#blockidflag) | Indicates whether the validator voted the last block, nil, or its vote was not received. | 3 | + | block_id_flag | [BlockIDFlag](/cometbft/v0.38/spec/core/Data_structures#blockidflag) | Indicates whether the validator voted the last block, nil, or its vote was not received. | 3 | * **Usage**: * Indicates whether a validator signed the last block, allowing for rewards based on validator availability. @@ -820,7 +820,7 @@ Most of the data structures used in ABCI are shared [common data structures](/co | validator | [Validator](#validator) | The validator that sent the vote. | 1 | | vote_extension | bytes | Non-deterministic extension provided by the sending validator's Application. | 3 | | extension_signature | bytes | Signature of the vote extension produced by the sending validator and verified by CometBFT. | 4 | - | block_id_flag | [BlockIDFlag](../core/Data_structures.mdx#blockidflag) | Indicates whether the validator voted the last block, nil, or its vote was not received. | 5 | + | block_id_flag | [BlockIDFlag](/cometbft/v0.38/spec/core/Data_structures#blockidflag) | Indicates whether the validator voted the last block, nil, or its vote was not received. | 5 | * **Usage**: * Indicates whether a validator signed the last block, allowing for rewards based on validator availability. diff --git a/cometbft/v0.38/spec/abci/Outline.mdx b/cometbft/v0.38/spec/abci/Outline.mdx index 16105925..5206ed5c 100644 --- a/cometbft/v0.38/spec/abci/Outline.mdx +++ b/cometbft/v0.38/spec/abci/Outline.mdx @@ -65,13 +65,13 @@ The first time a new blockchain is started, CometBFT calls `InitChain`. From the state. During the execution of an instance of consensus, which decides the block for a given height, and before method `FinalizeBlock` is called, methods `PrepareProposal`, `ProcessProposal`, `ExtendVote`, and `VerifyVoteExtension` may be called several times. See -[CometBFT's expected behavior](./CometBFTs-expected-behavior.mdx) for details on the possible +[CometBFT's expected behavior](/cometbft/v0.38/spec/abci/CometBFTs-expected-behavior) for details on the possible call sequences of these methods. -- [**InitChain:**](./Methods.mdx#initchain) This method initializes the blockchain. +- [**InitChain:**](/cometbft/v0.38/spec/abci/Methods#initchain) This method initializes the blockchain. CometBFT calls it once upon genesis. -- [**PrepareProposal:**](./Methods.mdx#prepareproposal) It allows the block +- [**PrepareProposal:**](/cometbft/v0.38/spec/abci/Methods#prepareproposal) It allows the block proposer to perform application-dependent work in a block before proposing it. This enables, for instance, batch optimizations to a block, which has been empirically demonstrated to be a key component for improved performance. Method `PrepareProposal` is called @@ -83,7 +83,7 @@ call sequences of these methods. (potentially) modified proposal, called *prepared proposal* in the `ResponsePrepareProposal`. The logic modifying the raw proposal MAY be non-deterministic. -- [**ProcessProposal:**](./Methods.mdx#processproposal) It allows a validator to +- [**ProcessProposal:**](/cometbft/v0.38/spec/abci/Methods#processproposal) It allows a validator to perform application-dependent work in a proposed block. This enables features such as immediate block execution, and allows the Application to reject invalid blocks. @@ -96,7 +96,7 @@ call sequences of these methods. ignore the invalid part of the prepared proposal at block execution time. The logic in `ProcessProposal` MUST be deterministic. -- [**ExtendVote:**](./Methods.mdx#extendvote) It allows applications to let their +- [**ExtendVote:**](/cometbft/v0.38/spec/abci/Methods#extendvote) It allows applications to let their validators do more than just validate within consensus. `ExtendVote` allows applications to include non-deterministic data, opaque to the consensus algorithm, to precommit messages (the final round of voting). The data, called *vote extension*, will be broadcast and received together with the @@ -107,7 +107,7 @@ call sequences of these methods. a 0-length byte array as its vote extension. The logic in `ExtendVote` MAY be non-deterministic. -- [**VerifyVoteExtension:**](./Methods.mdx#verifyvoteextension) It allows +- [**VerifyVoteExtension:**](/cometbft/v0.38/spec/abci/Methods#verifyvoteextension) It allows validators to validate the vote extension data attached to a precommit message. If the validation fails, the whole precommit message will be deemed invalid and ignored by consensus algorithm. This has a negative impact on liveness, i.e., if vote extensions repeatedly cannot be @@ -119,7 +119,7 @@ call sequences of these methods. a process receives a precommit message with a (possibly empty) vote extension, for the current height. It is not called for precommit votes received after the height is concluded but while waiting to accumulate more precommit votes. The logic in `VerifyVoteExtension` MUST be deterministic. -- [**FinalizeBlock:**](./Methods.mdx#finalizeblock) It delivers a decided block to the +- [**FinalizeBlock:**](/cometbft/v0.38/spec/abci/Methods#finalizeblock) It delivers a decided block to the Application. The Application must execute the transactions in the block deterministically and update its state accordingly. Cryptographic commitments to the block and transaction results, returned via the corresponding parameters in `ResponseFinalizeBlock`, are included in the header @@ -127,7 +127,7 @@ call sequences of these methods. When calling `FinalizeBlock` with a block, the consensus algorithm run by CometBFT guarantees that at least one non-byzantine validator has run `ProcessProposal` on that block. -- [**Commit:**](./Methods.mdx#commit) Instructs the Application to persist its +- [**Commit:**](/cometbft/v0.38/spec/abci/Methods#commit) Instructs the Application to persist its state. It is a fundamental part of CometBFT's crash-recovery mechanism that ensures the synchronization between CometBFT and the Application upon recovery. CometBFT calls it just after having persisted the data returned by calls to `ResponseFinalizeBlock`. The Application can now discard @@ -135,7 +135,7 @@ call sequences of these methods. ### Mempool methods -- [**CheckTx:**](./Methods.mdx#checktx) This method allows the Application to validate +- [**CheckTx:**](/cometbft/v0.38/spec/abci/Methods#checktx) This method allows the Application to validate transactions. Validation can be stateless (e.g., checking signatures ) or stateful (e.g., account balances). The type of validation performed is up to the application. If a transaction passes the validation, then CometBFT adds it to the mempool; otherwise the @@ -146,17 +146,17 @@ call sequences of these methods. ### Info methods -- [**Info:**](./Methods.mdx#info) Used to sync CometBFT with the Application during a +- [**Info:**](/cometbft/v0.38/spec/abci/Methods#info) Used to sync CometBFT with the Application during a handshake that happens upon recovery, or on startup when state-sync is used. -- [**Query:**](./Methods.mdx#query) This method can be used to query the Application for +- [**Query:**](/cometbft/v0.38/spec/abci/Methods#query) This method can be used to query the Application for information about the application state. ### State-sync methods State sync allows new nodes to rapidly bootstrap by discovering, fetching, and applying state machine (application) snapshots instead of replaying historical blocks. For more details, see the -[state sync documentation](../p2p/legacy-docs/messages/state-sync.mdx). +[state sync documentation](/cometbft/v0.38/spec/p2p/legacy-docs/messages/state-sync). New nodes discover and request snapshots from other nodes in the P2P network. A CometBFT node that receives a request for snapshots from a peer will call @@ -164,7 +164,7 @@ A CometBFT node that receives a request for snapshots from a peer will call snapshots. Note that the list does not contain the actual snapshots but metadata about them: height at which the snapshot was taken, application-specific verification data and more (see -[snapshot data type](./Methods.mdx#snapshot) for more details). After receiving a +[snapshot data type](/cometbft/v0.38/spec/abci/Methods#snapshot) for more details). After receiving a list of available snapshots from a peer, the new node can offer any of the snapshots in the list to its local Application via the `OfferSnapshot` method. The Application can check at this point the validity of the snapshot metadata. @@ -180,29 +180,29 @@ application with `ApplySnapshotChunk`. When all chunks have been applied, the Application's `AppHash` is retrieved via an `Info` query. To ensure that the sync proceeded correctly, CometBFT compares the local Application's `AppHash` to the `AppHash` stored on the blockchain (verified via -[light client verification](../light-client/verification.mdx)). +[light client verification](/cometbft/v0.38/spec/light-client/verification)). In summary: -- [**ListSnapshots:**](./Methods.mdx#listsnapshots) Used by nodes to discover available +- [**ListSnapshots:**](/cometbft/v0.38/spec/abci/Methods#listsnapshots) Used by nodes to discover available snapshots on peers. -- [**OfferSnapshot:**](./Methods.mdx#offersnapshot) When a node receives a snapshot from a +- [**OfferSnapshot:**](/cometbft/v0.38/spec/abci/Methods#offersnapshot) When a node receives a snapshot from a peer, CometBFT uses this method to offer the snapshot to the Application. -- [**LoadSnapshotChunk:**](./Methods.mdx#loadsnapshotchunk) Used by CometBFT to retrieve +- [**LoadSnapshotChunk:**](/cometbft/v0.38/spec/abci/Methods#loadsnapshotchunk) Used by CometBFT to retrieve snapshot chunks from the Application to send to peers. -- [**ApplySnapshotChunk:**](./Methods.mdx#applysnapshotchunk) Used by CometBFT to hand +- [**ApplySnapshotChunk:**](/cometbft/v0.38/spec/abci/Methods#applysnapshotchunk) Used by CometBFT to hand snapshot chunks to the Application. ### Other methods -Additionally, there is a [**Flush**](./Methods.mdx#flush) method that is called on every connection, -and an [**Echo**](./Methods.mdx#echo) method that is used for debugging. +Additionally, there is a [**Flush**](/cometbft/v0.38/spec/abci/Methods#flush) method that is called on every connection, +and an [**Echo**](/cometbft/v0.38/spec/abci/Methods#echo) method that is used for debugging. More details on managing state across connections can be found in the section on -[Managing Application State](./Requirements-for-the-Application.mdx#managing-the-application-state-and-related-topics). +[Managing Application State](/cometbft/v0.38/spec/abci/Requirements-for-the-Application#managing-the-application-state-and-related-topics). ## Proposal timeout @@ -377,8 +377,8 @@ passed on to the Application through ABCI++. It is the responsibility of the Application to handle evidence of misbehavior and exercise punishment. There are two forms of evidence: Duplicate Vote and Light Client Attack. More -information can be found in either [data structures](../core/Data_structures.mdx) -or [accountability](../light-client/Accountability.mdx). +information can be found in either [data structures](/cometbft/v0.38/spec/core/Data_structures) +or [accountability](/cometbft/v0.38/spec/light-client/Accountability). EvidenceType has the following protobuf format: diff --git a/cometbft/v0.38/spec/abci/Requirements-for-the-Application.mdx b/cometbft/v0.38/spec/abci/Requirements-for-the-Application.mdx index bce3d3ef..e5a7d887 100644 --- a/cometbft/v0.38/spec/abci/Requirements-for-the-Application.mdx +++ b/cometbft/v0.38/spec/abci/Requirements-for-the-Application.mdx @@ -433,7 +433,7 @@ The Application is expected to return a list of results MUST respect the same order as the list of transactions delivered via [`RequestFinalizeBlock`](/cometbft/v0.38/spec/abci/Methods#finalizeblock). This section discusses the fields inside this structure, along with the fields in -[`ResponseCheckTx`](./Methods.mdx#checktx), +[`ResponseCheckTx`](/cometbft/v0.38/spec/abci/Methods#checktx), whose semantics are similar. The `Info` and `Log` fields are @@ -619,7 +619,7 @@ the header, the validator set, and any included evidence in the block. The Application should be aware that honest validators *may* produce and broadcast blocks with up to the configured `MaxBytes` size. As a result, the consensus -[timeout parameters](../../docs/core/configuration.md#consensus-timeouts-explained) +[timeout parameters](/cometbft/v0.38/docs/core/configuration#consensus-timeouts-explained) adopted by nodes should be configured so as to account for the worst-case latency for the delivery of a full block with `MaxBytes` size to all validators. @@ -1022,7 +1022,7 @@ from the genesis file and light client RPC servers. It also calls `Info` to veri Once the state machine has been restored and CometBFT has gathered this additional information, it transitions to consensus. As of ABCI 2.0, CometBFT ensures the necessary conditions -to switch are met [RFC-100](https://github.com/cometbft/cometbft/blob/v0.38.x/docs/rfc/rfc-100-abci-vote-extension-propag.md#base-implementation-persist-and-propagate-extended-commit-history). +to switch are met [RFC-100](https://github.com/cometbft/cometbft/blob/v0.38.x/docs/rfc/rfc-100-abci-vote-extension-propag#base-implementation-persist-and-propagate-extended-commit-history). From the application's point of view, these operations are transparent, unless the application has just upgraded to ABCI 2.0. In that case, the application needs to be properly configured and aware of certain constraints in terms of when to provide vote extensions. More details can be found in the section below. @@ -1035,7 +1035,7 @@ Introducing vote extensions requires changes to the configuration of the applica First of all, switching to a version of CometBFT with vote extensions, requires a coordinated upgrade. For a detailed description on the upgrade path, please refer to the corresponding -[section](https://github.com/cometbft/cometbft/blob/v0.38.x/docs/rfc/rfc-100-abci-vote-extension-propag.md#upgrade-path) in RFC-100. +[section](https://github.com/cometbft/cometbft/blob/v0.38.x/docs/rfc/rfc-100-abci-vote-extension-propag#upgrade-path) in RFC-100. There is a newly introduced [**consensus parameter**](/cometbft/v0.38/spec/abci/Requirements-for-the-Application#consensus-parameters): `VoteExtensionsEnableHeight`. This parameter represents the height at which vote extensions are diff --git a/cometbft/v0.38/spec/consensus/Byzantine-Consensus-Algorithm.mdx b/cometbft/v0.38/spec/consensus/Byzantine-Consensus-Algorithm.mdx index c0928734..a0b4939e 100644 --- a/cometbft/v0.38/spec/consensus/Byzantine-Consensus-Algorithm.mdx +++ b/cometbft/v0.38/spec/consensus/Byzantine-Consensus-Algorithm.mdx @@ -18,7 +18,7 @@ order: 1 or precommit [vote](https://github.com/cometbft/cometbft/blob/af3bc47df982e271d4d340a3c5e0d773e440466d/types/vote.go#L50) for something. - A vote _at_ `(H,R)` is a vote signed with the bytes for `H` and `R` - included in its [sign-bytes](../core/Data_structures.mdx#vote). + included in its [sign-bytes](/cometbft/v0.38/spec/core/Data_structures#vote). - _+2/3_ is short for "more than 2/3" - _1/3+_ is short for "1/3 or more" - A set of +2/3 of prevotes for a particular block or `` at @@ -252,7 +252,7 @@ commit-set) are each justified in the JSet with no duplicitous vote signatures (by the committers). - **Lemma**: When a fork is detected by the existence of two - conflicting [commits](../core/Data_structures.mdx#commit), the + conflicting [commits](/cometbft/v0.38/spec/core/Data_structures#commit), the union of the JSets for both commits (if they can be compiled) must include double-signing by at least 1/3+ of the validator set. **Proof**: The commit cannot be at the same round, because that @@ -293,7 +293,7 @@ may make JSet verification/gossip logic easier to implement. ### Censorship Attacks Due to the definition of a block -[commit](https://github.com/cometbft/cometbft/blob/v0.38.x/docs/core/validators.md), any 1/3+ coalition of +[commit](https://github.com/cometbft/cometbft/blob/v0.38.x/docs/core/validators), any 1/3+ coalition of validators can halt the blockchain by not broadcasting their votes. Such a coalition can also censor particular transactions by rejecting blocks that include these transactions, though this would result in a diff --git a/cometbft/v0.38/spec/core/Data_structures.mdx b/cometbft/v0.38/spec/core/Data_structures.mdx index fecff3cb..6dbcba40 100644 --- a/cometbft/v0.38/spec/core/Data_structures.mdx +++ b/cometbft/v0.38/spec/core/Data_structures.mdx @@ -50,7 +50,7 @@ and a list of evidence of malfeasance (ie. signing conflicting votes). | Name | Type | Description | Validation | |--------|-------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------| | Header | [Header](#header) | Header corresponding to the block. This field contains information used throughout consensus and other areas of the protocol. To find out what it contains, visit [header](#header) | Must adhere to the validation rules of [header](#header) | -| Data | [Data](#data) | Data contains a list of transactions. The contents of the transaction is unknown to CometBFT. | This field can be empty or populated, but no validation is performed. Applications can perform validation on individual transactions prior to block creation using [checkTx](https://github.com/cometbft/cometbft/blob/v0.38.x/spec/abci/abci%2B%2B_methods.mdx#checktx). +| Data | [Data](#data) | Data contains a list of transactions. The contents of the transaction is unknown to CometBFT. | This field can be empty or populated, but no validation is performed. Applications can perform validation on individual transactions prior to block creation using [checkTx](https://github.com/cometbft/cometbft/blob/v0.38.x/spec/abci/abci%2B%2B_methods#checktx). | Evidence | [EvidenceList](#evidencelist) | Evidence contains a list of infractions committed by validators. | Can be empty, but when populated the validations rules from [evidenceList](#evidencelist) apply | | LastCommit | [Commit](#commit) | `LastCommit` includes one vote for every validator. All votes must either be for the previous block, nil or absent. If a vote is for the previous block it must have a valid signature from the corresponding validator. The sum of the voting power of the validators that voted must be greater than 2/3 of the total voting power of the complete validator set. The number of votes in a commit is limited to 10000 (see `types.MaxVotesCount`). | Must be empty for the initial height and must adhere to the validation rules of [commit](#commit). | @@ -123,7 +123,7 @@ the data in the current block, the previous block, and the results returned by t | Version | [Version](#version) | Version defines the application and block versions being used. | Must adhere to the validation rules of [Version](#version) | | ChainID | String | ChainID is the ID of the chain. This must be unique to your chain. | ChainID must be less than 50 bytes. | | Height | uint64 | Height is the height for this header. | Must be > 0, >= initialHeight, and == previous Height+1 | -| Time | [Time](#time) | The timestamp is equal to the weighted median of validators present in the last commit. Read more on time in the [BFT-time section](../consensus/BFT-Time.mdx). Note: the timestamp of a vote must be greater by at least one millisecond than that of the block being voted on. | Time must be >= previous header timestamp + consensus parameters TimeIotaMs. The timestamp of the first block must be equal to the genesis time (since there's no votes to compute the median). | +| Time | [Time](#time) | The timestamp is equal to the weighted median of validators present in the last commit. Read more on time in the [BFT-time section](/cometbft/v0.38/spec/consensus/BFT-Time). Note: the timestamp of a vote must be greater by at least one millisecond than that of the block being voted on. | Time must be >= previous header timestamp + consensus parameters TimeIotaMs. The timestamp of the first block must be equal to the genesis time (since there's no votes to compute the median). | | LastBlockID | [BlockID](#blockid) | BlockID of the previous block. | Must adhere to the validation rules of [blockID](#blockid). The first block has `block.Header.LastBlockID == BlockID{}`. | | LastCommitHash | slice of bytes (`[]byte`) | MerkleRoot of the lastCommit's signatures. The signatures represent the validators that committed to the last block. The first block has an empty slices of bytes for the hash. | Must be of length 32 | | DataHash | slice of bytes (`[]byte`) | MerkleRoot of the hash of transactions. **Note**: The transactions are hashed before being included in the merkle tree, the leaves of the Merkle tree are the hashes, not the transactions themselves. | Must be of length 32 | @@ -144,7 +144,7 @@ versioning that this can refer to) | Name | type | Description | Validation | |-------|--------|---------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------| | Block | uint64 | This number represents the block version and must be the same throughout an operational network | Must be equal to block version being used in a network (`block.Version.Block == state.Version.Consensus.Block`) | -| App | uint64 | App version is decided on by the application. Read [here](https://github.com/cometbft/cometbft/blob/v0.38.x/spec/abci/abci++_app_requirements.md) | `block.Version.App == state.Version.Consensus.App` | +| App | uint64 | App version is decided on by the application. Read [here](https://github.com/cometbft/cometbft/blob/v0.38.x/spec/abci/abci++_app_requirements) | `block.Version.App == state.Version.Consensus.App` | ## BlockID @@ -155,7 +155,7 @@ The `BlockID` contains two distinct Merkle roots of the block. The `BlockID` inc | Hash | slice of bytes (`[]byte`) | MerkleRoot of all the fields in the header (ie. `MerkleRoot(header)`. | hash must be of length 32 | | PartSetHeader | [PartSetHeader](#partsetheader) | Used for secure gossiping of the block during consensus, is the MerkleRoot of the complete serialized block cut into parts (ie. `MerkleRoot(MakeParts(block))`). | Must adhere to the validation rules of [PartSetHeader](#partsetheader) | -See [MerkleRoot](./encoding.md#merkleroot) for details. +See [MerkleRoot](/cometbft/v0.38/spec/core/encoding#merkleroot) for details. ## PartSetHeader @@ -224,7 +224,7 @@ to reconstruct the vote set given the validator set. | Signature | [Signature](#signature) | Signature corresponding to the validators participation in consensus. | The length of the signature must be > 0 and < than 64 | NOTE: `ValidatorAddress` and `Timestamp` fields may be removed in the future -(see [ADR-25](https://github.com/cometbft/cometbft/blob/v0.38.x/docs/architecture/tendermint-core/adr-025-commit.md)). +(see [ADR-25](https://github.com/cometbft/cometbft/blob/v0.38.x/docs/architecture/tendermint-core/adr-025-commit)). ## ExtendedCommitSig @@ -359,7 +359,7 @@ enum SignedMsgType { Signatures in CometBFT are raw bytes representing the underlying signature. -See the [signature spec](./encoding.md#key-types) for more. +See the [signature spec](/cometbft/v0.38/spec/core/encoding#key-types) for more. ## EvidenceList @@ -373,7 +373,7 @@ EvidenceList is a simple wrapper for a list of evidence: Evidence in CometBFT is used to indicate breaches in the consensus by a validator. -More information on how evidence works in CometBFT can be found [here](../consensus/Evidence.mdx) +More information on how evidence works in CometBFT can be found [here](/cometbft/v0.38/spec/consensus/Evidence) ### DuplicateVoteEvidence @@ -393,7 +393,7 @@ in the same round of the same height. Votes are lexicographically sorted on `Blo `LightClientAttackEvidence` is a generalized evidence that captures all forms of known attacks on a light client such that a full node can verify, propose and commit the evidence on-chain for punishment of the malicious validators. There are three forms of attacks: Lunatic, Equivocation -and Amnesia. These attacks are exhaustive. You can find a more detailed overview of this [here](../light-client/Accountability.mdx#the-misbehavior-of-faulty-validators) +and Amnesia. These attacks are exhaustive. You can find a more detailed overview of this [here](/cometbft/v0.38/spec/light-client/Accountability#the-misbehavior-of-faulty-validators) | Name | Type | Description | Validation | |----------------------|------------------------------------|----------------------------------------------------------------------|------------------------------------------------------------------| @@ -405,11 +405,11 @@ and Amnesia. These attacks are exhaustive. You can find a more detailed overview ## LightBlock -LightBlock is the core data structure of the [light client](../light-client/Light-Client-Specification.mdx). It combines two data structures needed for verification ([signedHeader](#signedheader) & [validatorSet](#validatorset)). +LightBlock is the core data structure of the [light client](/cometbft/v0.38/spec/light-client/Light-Client-Specification). It combines two data structures needed for verification ([signedHeader](#signedheader) & [validatorSet](#validatorset)). | Name | Type | Description | Validation | |--------------|-------------------------------|----------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------| -| SignedHeader | [SignedHeader](#signedheader) | The header and commit, these are used for verification purposes. To find out more visit [light client docs](../light-client/Light-Client-Specification.mdx) | Must not be nil and adhere to the validation rules of [signedHeader](#signedheader) | +| SignedHeader | [SignedHeader](#signedheader) | The header and commit, these are used for verification purposes. To find out more visit [light client docs](/cometbft/v0.38/spec/light-client/Light-Client-Specification) | Must not be nil and adhere to the validation rules of [signedHeader](#signedheader) | | ValidatorSet | [ValidatorSet](#validatorset) | The validatorSet is used to help with verify that the validators in that committed the infraction were truly in the validator set. | Must not be nil and adhere to the validation rules of [validatorSet](#validatorset) | The `SignedHeader` and `ValidatorSet` are linked by the hash of the validator set(`SignedHeader.ValidatorsHash == ValidatorSet.Hash()`. diff --git a/cometbft/v0.38/spec/light-client/verification.mdx b/cometbft/v0.38/spec/light-client/verification.mdx index 99efdb3f..cf36bf0c 100644 --- a/cometbft/v0.38/spec/light-client/verification.mdx +++ b/cometbft/v0.38/spec/light-client/verification.mdx @@ -27,7 +27,7 @@ Given a known bound `TRUSTED_PERIOD`, and a block `b` with header `h` generated in `validators(b.Header.NextValidatorsHash)` is correct until time `b.Header.Time + TRUSTED_PERIOD`. *Assumption*: "correct" is defined w.r.t. realtime (some Newtonian global notion of time, i.e., wall time), -while `Header.Time` corresponds to the [BFT time](../consensus/BFT-Time.mdx). In this note, we assume that clocks of correct processes +while `Header.Time` corresponds to the [BFT time](/cometbft/v0.38/spec/consensus/BFT-Time). In this note, we assume that clocks of correct processes are synchronized (for example using NTP), and therefore there is bounded clock drift (`CLOCK_DRIFT`) between local clocks and BFT time. More precisely, for every correct light client process and every `header.Time` (i.e. BFT Time, for a header correctly generated by the Tendermint consensus), the following inequality holds: `Header.Time < now + CLOCK_DRIFT`, @@ -47,7 +47,7 @@ Mechanisms like `fork accountability` and `evidence submission` are defined in t they incentivize validators to follow the protocol specification defined in this document. If they don't, and we have 1/3 (or more) faulty validators, safety may be violated. Our approach then is to *detect* these cases (after the fact), and take suitable repair actions (automatic and social). -This is discussed in document on [Fork accountability](./Accountability.mdx). +This is discussed in document on [Fork accountability](/cometbft/v0.38/spec/light-client/Accountability). The term "trusted" above indicates that the correctness of the protocol depends on this assumption. It is in the responsibility of the user that runs the light client to make sure that the risk diff --git a/cometbft/v0.38/spec/p2p/reactor-api/API-for-Reactors.mdx b/cometbft/v0.38/spec/p2p/reactor-api/API-for-Reactors.mdx index e4b2910b..3b6954df 100644 --- a/cometbft/v0.38/spec/p2p/reactor-api/API-for-Reactors.mdx +++ b/cometbft/v0.38/spec/p2p/reactor-api/API-for-Reactors.mdx @@ -328,7 +328,7 @@ The `TrySend()` method is a _non-blocking_ method, it _immediately_ returns [switch-type]: https://github.com/cometbft/cometbft/blob/v0.38.x/p2p/switch.go [reactor-interface]: https://github.com/cometbft/cometbft/blob/v0.38.x/p2p/base_reactor.go -[reactor-registration]: ./reactor.md#registration -[reactor-channels]: ./reactor.md#registration -[reactor-addpeer]: ./reactor.md#peer-management -[reactor-removepeer]: ./reactor.md#stop-peer +[reactor-registration]: /cometbft/v0.38/spec/p2p/reactor-api/reactor#registration +[reactor-channels]: /cometbft/v0.38/spec/p2p/reactor-api/reactor#registration +[reactor-addpeer]: /cometbft/v0.38/spec/p2p/reactor-api/reactor#peer-management +[reactor-removepeer]: /cometbft/v0.38/spec/p2p/reactor-api/reactor#stop-peer diff --git a/enterprise/components/interoperability/deployment.mdx b/enterprise/components/interoperability/deployment.mdx index 6d77f02c..6ad7af9c 100644 --- a/enterprise/components/interoperability/deployment.mdx +++ b/enterprise/components/interoperability/deployment.mdx @@ -42,7 +42,7 @@ This document explains how an IBC v2 deployment works end-to-end to support mint - Implementation: [cosmos/solidity-ibc-eureka attestation](https://github.com/cosmos/solidity-ibc-eureka/tree/main/contracts/light-clients/attestation) - **Interchain Fungible Token (IFT)** — A set of rules and interfaces for creating and managing fungible tokens that can be transferred across different blockchain networks using ICS-27 GMP. - - Implementation: [cosmos/solidity-ibc-eureka IFTBase.sol](https://github.com/cosmos/solidity-ibc-eureka/blob/mariuszzak/ift/contracts/IFTBase.sol) + - Implementation: [cosmos/solidity-ibc-eureka IFTBase.sol](https://github.com/cosmos/solidity-ibc-eureka/blob/815ddaf194c81f2098c88afb9d73108687bb48eb/contracts/utils/IFTBaseUpgradeable.sol) ### Off-Chain diff --git a/evm/next/documentation/custom-improvement-proposals.mdx b/evm/next/documentation/custom-improvement-proposals.mdx index 81650adc..c69c3015 100644 --- a/evm/next/documentation/custom-improvement-proposals.mdx +++ b/evm/next/documentation/custom-improvement-proposals.mdx @@ -53,7 +53,4 @@ Due to continuous changes in the users' interaction with the protocol, and to in This approach gives developers the ability to react to security issues or market conditions, while keeping the chain's participants in the loop. -## Additional Resources[​](#additional-resources "Direct link to Additional Resources") - -1. [Cosmos EVM Custom EIPs](https://github.com/cosmos/evm/blob/main/app/eips/README.md): please refer to this document for a detailed description of how opcodes and custom improvement proposals have to be used in the Cosmos EVM framework. diff --git a/evm/next/documentation/smart-contracts/precompiles/overview.mdx b/evm/next/documentation/smart-contracts/precompiles/overview.mdx index 3d812bfc..9f6f56f9 100644 --- a/evm/next/documentation/smart-contracts/precompiles/overview.mdx +++ b/evm/next/documentation/smart-contracts/precompiles/overview.mdx @@ -110,7 +110,6 @@ bankPrecompile, err := bankprecompile.NewPrecompile( ) ``` -**Source:** [`evmd/precompiles.go:122`](https://github.com/cosmos/evm/blob/main/evmd/precompiles.go#L122) ### Required Interfaces diff --git a/evm/v0.4.x/documentation/concepts/accounts.mdx b/evm/v0.4.x/documentation/concepts/accounts.mdx index a2a206bd..fd193f05 100644 --- a/evm/v0.4.x/documentation/concepts/accounts.mdx +++ b/evm/v0.4.x/documentation/concepts/accounts.mdx @@ -39,7 +39,7 @@ Cosmos EVM defines its own custom `Account` type to implement a HD wallet that i The root HD path for EVM-based accounts is `m/44'/60'/0'/0`. It is recommended to use the Coin type `60` to support Ethereum type accounts, unlike many other Cosmos chains that use Coin type `118` ([list of coin types](https://github.com/satoshilabs/slips/blob/master/slip-0044.md) -The custom Cosmos EVM [EthAccount](https://github.com/cosmos/evm/blob/v0.4.1/types/account.go#L28-L33) satisfies the `AccountI` interface from the Cosmos SDK auth module and includes additional fields that are required for Ethereum type addresses: +The custom Cosmos EVM EthAccount satisfies the `AccountI` interface from the Cosmos SDK auth module and includes additional fields that are required for Ethereum type addresses: ``` // EthAccountI represents the interface of an EVM compatible accounttype EthAccountI interface { authtypes.AccountI // EthAddress returns the ethereum Address representation of the AccAddress EthAddress() common.Address // CodeHash is the keccak256 hash of the contract code (if any) GetCodeHash() common.Hash // SetCodeHash sets the code hash to the account fields SetCodeHash(code common.Hash) error // Type returns the type of Ethereum Account (EOA or Contract) Type() int8} diff --git a/evm/v0.4.x/documentation/custom-improvement-proposals.mdx b/evm/v0.4.x/documentation/custom-improvement-proposals.mdx index b881e32c..8728aa00 100644 --- a/evm/v0.4.x/documentation/custom-improvement-proposals.mdx +++ b/evm/v0.4.x/documentation/custom-improvement-proposals.mdx @@ -53,7 +53,4 @@ Due to continuous changes in the users' interaction with the protocol, and to in This approach gives developers the ability to react to security issues or market conditions, while keeping the chain's participants in the loop. -## Additional Resources[​](#additional-resources "Direct link to Additional Resources") - -1. [Cosmos EVM Custom EIPs](https://github.com/cosmos/evm/blob/main/app/eips/README.md): please refer to this document for a detailed description of how opcodes and custom improvement proposals have to be used in the Cosmos EVM framework. diff --git a/evm/v0.4.x/documentation/smart-contracts/precompiles/p256.mdx b/evm/v0.4.x/documentation/smart-contracts/precompiles/p256.mdx index b6054e73..5d4a94ed 100644 --- a/evm/v0.4.x/documentation/smart-contracts/precompiles/p256.mdx +++ b/evm/v0.4.x/documentation/smart-contracts/precompiles/p256.mdx @@ -11,7 +11,6 @@ The P256 precompile provides native support for verifying secp256r1 (P-256) elli **Address**: `0x0000000000000000000000000000000000000100` -**Related Standards**: [EIP-7212](https://eips.ethereum.org/EIPS/eip-7212) ## Gas Costs diff --git a/evm/v0.4.x/documentation/smart-contracts/predeployed-contracts/implementation-guide.mdx b/evm/v0.4.x/documentation/smart-contracts/predeployed-contracts/implementation-guide.mdx index 5da47d6b..8c4c79f8 100644 --- a/evm/v0.4.x/documentation/smart-contracts/predeployed-contracts/implementation-guide.mdx +++ b/evm/v0.4.x/documentation/smart-contracts/predeployed-contracts/implementation-guide.mdx @@ -301,5 +301,5 @@ preinstalls := append(evmtypes.DefaultPreinstalls, customPreinstall) - [EIP-1014: CREATE2 Specification](https://eips.ethereum.org/EIPS/eip-1014) - Understanding deterministic deployment - [Multicall3 Documentation](https://github.com/mds1/multicall) - Official Multicall3 repository -- [Permit2 Introduction](https://blog.uniswap.org/permit2) - Uniswap's Permit2 design +- [Permit2 Introduction](https://blog.uniswap.org/permit2-and-universal-router) - Uniswap's Permit2 design - [Safe Contracts](https://github.com/safe-global/safe-contracts) - Safe multisig implementation \ No newline at end of file diff --git a/evm/v0.4.x/documentation/smart-contracts/predeployed-contracts/permit2.mdx b/evm/v0.4.x/documentation/smart-contracts/predeployed-contracts/permit2.mdx index e4ba41cf..676d2d3e 100644 --- a/evm/v0.4.x/documentation/smart-contracts/predeployed-contracts/permit2.mdx +++ b/evm/v0.4.x/documentation/smart-contracts/predeployed-contracts/permit2.mdx @@ -409,7 +409,7 @@ class PaymentProcessor { ## Further Reading -- [Permit2 Introduction Blog](https://blog.uniswap.org/permit2) +- [Permit2 Introduction Blog](https://blog.uniswap.org/permit2-and-universal-router) - [Permit2 GitHub Repository](https://github.com/Uniswap/permit2) - [EIP-2612: Permit Extension](https://eips.ethereum.org/EIPS/eip-2612) - [Security Best Practices](https://github.com/Uniswap/permit2/blob/main/v0.4.x/security.md) \ No newline at end of file diff --git a/evm/v0.5.0/documentation/concepts/accounts.mdx b/evm/v0.5.0/documentation/concepts/accounts.mdx index 4448c363..0b6585db 100644 --- a/evm/v0.5.0/documentation/concepts/accounts.mdx +++ b/evm/v0.5.0/documentation/concepts/accounts.mdx @@ -39,7 +39,7 @@ Cosmos EVM defines its own custom `Account` type to implement a HD wallet that i The root HD path for EVM-based accounts is `m/44'/60'/0'/0`. It is recommended to use the Coin type `60` to support Ethereum type accounts, unlike many other Cosmos chains that use Coin type `118` ([list of coin types](https://github.com/satoshilabs/slips/blob/master/slip-0044.md)). -The custom Cosmos EVM [EthAccount](https://github.com/cosmos/evm/blob/v0.4.1/types/account.go#L28-L33) satisfies the `AccountI` interface from the Cosmos SDK auth module and includes additional fields that are required for Ethereum type addresses: +The custom Cosmos EVM EthAccount satisfies the `AccountI` interface from the Cosmos SDK auth module and includes additional fields that are required for Ethereum type addresses: ```go "EthAccountI Interface" expandable // EthAccountI represents the interface of an EVM compatible account diff --git a/evm/v0.5.0/documentation/custom-improvement-proposals.mdx b/evm/v0.5.0/documentation/custom-improvement-proposals.mdx index 1af2c3fc..8d04560f 100644 --- a/evm/v0.5.0/documentation/custom-improvement-proposals.mdx +++ b/evm/v0.5.0/documentation/custom-improvement-proposals.mdx @@ -53,7 +53,4 @@ Due to continuous changes in the users' interaction with the protocol, and to in This approach gives developers the ability to react to security issues or market conditions, while keeping the chain's participants in the loop. -## Additional Resources[​](#additional-resources "Direct link to Additional Resources") - -1. [Cosmos EVM Custom EIPs](https://github.com/cosmos/evm/blob/main/app/eips/README.md): please refer to this document for a detailed description of how opcodes and custom improvement proposals have to be used in the Cosmos EVM framework. diff --git a/evm/v0.5.0/documentation/getting-started/build-a-chain/additional-configuration/predeployed-contracts.mdx b/evm/v0.5.0/documentation/getting-started/build-a-chain/additional-configuration/predeployed-contracts.mdx index 3d9fdd86..f71cfac8 100644 --- a/evm/v0.5.0/documentation/getting-started/build-a-chain/additional-configuration/predeployed-contracts.mdx +++ b/evm/v0.5.0/documentation/getting-started/build-a-chain/additional-configuration/predeployed-contracts.mdx @@ -361,7 +361,7 @@ preinstalls := append(evmtypes.DefaultPreinstalls, customPreinstall) ### Contract Documentation - [Multicall3 Documentation](https://github.com/mds1/multicall) - Official Multicall3 repository -- [Permit2 Introduction](https://blog.uniswap.org/permit2) - Uniswap's Permit2 design +- [Permit2 Introduction](https://blog.uniswap.org/permit2-and-universal-router) - Uniswap's Permit2 design - [Safe Contracts](https://github.com/safe-global/safe-contracts) - Safe multisig implementation ### Cosmos EVM Resources diff --git a/evm/v0.5.0/documentation/smart-contracts/precompiles/overview.mdx b/evm/v0.5.0/documentation/smart-contracts/precompiles/overview.mdx index 6d2b2975..4d4eba59 100644 --- a/evm/v0.5.0/documentation/smart-contracts/precompiles/overview.mdx +++ b/evm/v0.5.0/documentation/smart-contracts/precompiles/overview.mdx @@ -110,7 +110,6 @@ bankPrecompile, err := bankprecompile.NewPrecompile( ) ``` -**Source:** [`evmd/precompiles.go:122`](https://github.com/cosmos/evm/blob/main/evmd/precompiles.go#L122) ### Required Interfaces diff --git a/evm/v0.5.0/documentation/smart-contracts/predeployed-contracts/permit2.mdx b/evm/v0.5.0/documentation/smart-contracts/predeployed-contracts/permit2.mdx index c528571d..683d96c6 100644 --- a/evm/v0.5.0/documentation/smart-contracts/predeployed-contracts/permit2.mdx +++ b/evm/v0.5.0/documentation/smart-contracts/predeployed-contracts/permit2.mdx @@ -409,7 +409,7 @@ class PaymentProcessor { ## Further Reading -- [Permit2 Introduction Blog](https://blog.uniswap.org/permit2) +- [Permit2 Introduction Blog](https://blog.uniswap.org/permit2-and-universal-router) - [Permit2 GitHub Repository](https://github.com/Uniswap/permit2) - [EIP-2612: Permit Extension](https://eips.ethereum.org/EIPS/eip-2612) - [Security Best Practices](https://github.com/Uniswap/permit2/blob/main/docs/security.md) \ No newline at end of file diff --git a/hub/v25/hub-tutorials/join-testnet.mdx b/hub/v25/hub-tutorials/join-testnet.mdx index a86273c3..52275d86 100644 --- a/hub/v25/hub-tutorials/join-testnet.mdx +++ b/hub/v25/hub-tutorials/join-testnet.mdx @@ -6,7 +6,7 @@ description: >- --- Visit the [testnets repo](https://github.com/cosmos/testnets) for the most up-to-date information on the currently available public testnets: -* Interchain Security (ICS) Testnet: [`provider`](https://github.com/cosmos/testnets/blob/master/interchain-security/provider/README.md) +* Interchain Security (ICS) Testnet: [`provider`](https://github.com/cosmos/testnets/tree/master/interchain-security) * Release Testnet: [`theta-testnet-001`](https://github.com/cosmos/testnets/blob/master/legacy/theta-testnet-001/README.md) ## How to Join @@ -22,7 +22,7 @@ You can set up a testnet node with a single command using one of the options bel ## Create a Validator (Optional) -If you want to create a validator in either testnet, request tokens through the [faucet Discord channel](https://discord.com/channels/669268347736686612/953697793476821092) and follow the [this guide](https://github.com/cosmos/testnets/blob/master/interchain-security/VALIDATOR_JOINING_GUIDE.md#creating-a-validator-on-the-provider-chain). If you are creating a validator in the Release Testnet, you can disregard the instructions about joining live consumer chains. +If you want to create a validator in either testnet, request tokens through the [faucet Discord channel](https://discord.com/channels/669268347736686612/953697793476821092) and follow the [this guide](https://github.com/cosmos/testnets/blob/master/interchain-security/pion-1/README.md#creating-a-validator-on-the-provider-chain). If you are creating a validator in the Release Testnet, you can disregard the instructions about joining live consumer chains. ## Upgrading Your Node diff --git a/hub/v25/index.mdx b/hub/v25/index.mdx index 9e2aca4b..9478967b 100644 --- a/hub/v25/index.mdx +++ b/hub/v25/index.mdx @@ -27,18 +27,15 @@ These community-maintained web and mobile wallets allow you to store & transfer * [Citadel.One](https://citadel.one/#mobile) - Android, iOS * [Cobo](https://cobo.com/) - Android, iOS * [Crypto.com](https://crypto.com/) - Android, iOS -* [Huobi Wallet](https://www.huobiwallet.com/) - Android, iOS * [ShapeShift](https://app.shapeshift.com/) - Android, iOS, Web * imToken - Android, iOS * [Math Wallet](https://www.mathwallet.org/en/) - Android, iOS, Web -* [Rainbow Wallet](https://www.rainbow.one) - Android, iOS * Trust Wallet - Android, iOS * [Komodo Wallet](https://komodoplatform.com/en/wallets) ## Metamask Snaps * [Leap Wallet](https://www.leapwallet.io/snaps) -* [Mystic Lab](https://metamask.mysticlabs.xyz/) ## Cosmos Hub Explorers @@ -47,10 +44,8 @@ These block explorers allow you to search, view and analyze Cosmos Hub data—li * [Mintscan](https://mintscan.io) * [Numia](https://www.datalenses.zone/chain/cosmos) * [ATOMScan](https://atomscan.com) -* [IOBScan](https://cosmoshub.iobscan.io/) * [Ping.Pub](https://ping.pub/cosmos) * [BronBro](https://monitor.bronbro.io/d/cosmos-stats/cosmos) -* [SmartStake](https://cosmos.smartstake.io/stats) ## Cosmos Hub CLI diff --git a/sdk/v0.53/build/tooling/cosmovisor.mdx b/sdk/v0.53/build/tooling/cosmovisor.mdx index 96c67d9c..f5afe422 100644 --- a/sdk/v0.53/build/tooling/cosmovisor.mdx +++ b/sdk/v0.53/build/tooling/cosmovisor.mdx @@ -374,7 +374,7 @@ Update app to the latest version (e.g. v0.50.0). -Migration plans are defined using the `x/upgrade` module and described in [In-Place Store Migrations](https://github.com/cosmos/cosmos-sdk/blob/main/docs/learn/advanced/15-upgrade.md). Migrations can perform any deterministic state change. +Migration plans are defined using the `x/upgrade` module and described in [In-Place Store Migrations](sdk/v0.53/learn/advanced/upgrade). Migrations can perform any deterministic state change. The migration plan to upgrade the simapp from v0.47 to v0.50 is defined in `simapp/upgrade.go`. diff --git a/sdk/v0.53/security/bug-bounty.mdx b/sdk/v0.53/security/bug-bounty.mdx index 56450693..012dbc2c 100644 --- a/sdk/v0.53/security/bug-bounty.mdx +++ b/sdk/v0.53/security/bug-bounty.mdx @@ -98,8 +98,7 @@ public disclosure. This approach aligns with practices used by other major protocols, such as **Ethereum's Geth** (see https://geth.ethereum.org/docs/developers/geth-developer/disclosures), -**Bitcoin Core** (see https://bitcoincore.org/en/security-advisories/), -and **Zcash** (see https://z.cash/technology/security-advisories/). +**Bitcoin Core** (see https://bitcoincore.org/en/security-advisories/). Premature disclosure can place unpatched networks at risk. Silent remediation allows operators time to upgrade before vulnerability diff --git a/skip-go/widget/configuration.mdx b/skip-go/widget/configuration.mdx index d80e84b4..63e5d5ee 100644 --- a/skip-go/widget/configuration.mdx +++ b/skip-go/widget/configuration.mdx @@ -357,7 +357,7 @@ onDestinationAssetUpdated?: (props: { If your application has already connected to a user's wallet (e.g., via MetaMask for EVM networks, Phantom for Solana, or Keplr for Cosmos), you **must provide both** the `connectedAddresses` and corresponding signer functions in order to enable the widget's injected wallet functionality. See an implementation example [here](https://github.com/skip-mev/skip-go/tree/staging/examples/nextjs/src/app/injected/page.tsx). -`WalletClient` comes from the [`viem` package](https://viem.sh/docs/clients/wallet.html). `Adapter` comes from the [`@solana/wallet-adapter-base` package](https://solana.com/developers/cookbook/wallets/connect-wallet-react). And `OfflineSigner` comes from the [`@cosmjs` package](https://github.com/cosmos/cosmjs). +`WalletClient` comes from the [`viem` package](https://viem.sh/docs/clients/wallet). `Adapter` comes from the [`@solana/wallet-adapter-base` package](https://solana.com/developers/cookbook/wallets/connect-wallet-react). And `OfflineSigner` comes from the [`@cosmjs` package](https://github.com/cosmos/cosmjs). - **Type:** `Record` From ee09dc8ee9d59ad80ed97518a61795947d7efbcf Mon Sep 17 00:00:00 2001 From: Evan <87997759+evanorti@users.noreply.github.com> Date: Fri, 20 Feb 2026 15:13:07 -0500 Subject: [PATCH 02/13] fix links --- cometbft/v0.38/docs/qa/CometBFT-QA-38.mdx | 2 +- cometbft/v0.38/docs/qa/TMCore-QA-34.mdx | 2 +- cometbft/v0.38/docs/qa/TMCore-QA-37.mdx | 2 +- .../smart-contracts/predeployed-contracts/permit2.mdx | 4 ++-- hub/v25/governance/formatting.mdx | 2 +- .../governance/proposal-types/community-pool-spend.mdx | 2 +- hub/v25/resources/archives.mdx | 2 +- ibc/v10.1.x/migrations/sdk-to-v1.mdx | 6 +++--- ibc/v4.6.x/ibc/proto-docs.mdx | 2 +- ibc/v4.6.x/migrations/sdk-to-v1.mdx | 6 +++--- ibc/v5.4.x/migrations/sdk-to-v1.mdx | 6 +++--- ibc/v6.3.x/ibc/proto-docs.mdx | 2 +- ibc/v6.3.x/migrations/sdk-to-v1.mdx | 6 +++--- ibc/v7.8.x/middleware/ics29-fee/fee-distribution.mdx | 4 ++-- ibc/v7.8.x/migrations/sdk-to-v1.mdx | 6 +++--- ibc/v8.5.x/migrations/sdk-to-v1.mdx | 6 +++--- sdk/next/changelog/release-notes.mdx | 2 +- .../adr-016-validator-consensus-key-rotation.mdx | 2 +- .../adr-033-protobuf-inter-module-comm.mdx | 2 +- .../adr-040-storage-and-smt-state-commitments.mdx | 4 ++-- .../build/architecture/adr-049-state-sync-hooks.mdx | 2 +- .../architecture/adr-054-semver-compatible-modules.mdx | 2 +- sdk/v0.47/build/architecture/adr-059-test-scopes.mdx | 10 +++++----- sdk/v0.47/build/migrations/upgrading.mdx | 2 +- sdk/v0.47/build/spec/addresses/bech32.mdx | 2 +- sdk/v0.47/build/tooling/cosmovisor.mdx | 2 +- sdk/v0.47/build/tooling/hubl.mdx | 2 +- sdk/v0.47/learn/intro/overview.mdx | 2 +- sdk/v0.47/user/run-node/keyring.mdx | 4 ++-- sdk/v0.47/user/run-node/run-production.mdx | 2 +- sdk/v0.50/build/abci/introduction.mdx | 2 +- .../adr-016-validator-consensus-key-rotation.mdx | 2 +- .../adr-033-protobuf-inter-module-comm.mdx | 2 +- .../adr-040-storage-and-smt-state-commitments.mdx | 2 +- .../build/architecture/adr-049-state-sync-hooks.mdx | 2 +- .../architecture/adr-054-semver-compatible-modules.mdx | 2 +- sdk/v0.50/build/architecture/adr-059-test-scopes.mdx | 10 +++++----- .../build/architecture/adr-076-tx-malleability.mdx | 6 +++--- sdk/v0.50/build/building-modules/simulator.mdx | 6 +++--- sdk/v0.50/build/migrations/upgrade-reference.mdx | 2 +- sdk/v0.50/build/tooling/cosmovisor.mdx | 2 +- sdk/v0.50/build/tooling/hubl.mdx | 2 +- sdk/v0.50/learn/intro/overview.mdx | 2 +- sdk/v0.50/user/run-node/keyring.mdx | 4 ++-- sdk/v0.50/user/run-node/run-production.mdx | 2 +- .../adr-016-validator-consensus-key-rotation.mdx | 2 +- .../adr-033-protobuf-inter-module-comm.mdx | 4 ++-- .../adr-040-storage-and-smt-state-commitments.mdx | 2 +- .../build/architecture/adr-049-state-sync-hooks.mdx | 2 +- .../architecture/adr-054-semver-compatible-modules.mdx | 2 +- sdk/v0.53/build/architecture/adr-059-test-scopes.mdx | 10 +++++----- .../build/architecture/adr-076-tx-malleability.mdx | 6 +++--- sdk/v0.53/build/migrations/upgrade-reference.mdx | 2 +- sdk/v0.53/user/run-node/keyring.mdx | 4 ++-- 54 files changed, 91 insertions(+), 91 deletions(-) diff --git a/cometbft/v0.38/docs/qa/CometBFT-QA-38.mdx b/cometbft/v0.38/docs/qa/CometBFT-QA-38.mdx index 85abd142..92820b60 100644 --- a/cometbft/v0.38/docs/qa/CometBFT-QA-38.mdx +++ b/cometbft/v0.38/docs/qa/CometBFT-QA-38.mdx @@ -41,7 +41,7 @@ is described [here](/cometbft/v0.38/docs/qa/TMCore-QA-37#finding-the-saturation- The following table summarizes the results for the different experiments (extracted from -[`v038_report_tabbed.txt`](/cometbft/v0.38/docs/qa/img38/200nodes/v038_report_tabbed.txt)). The X axis +[`v038_report_tabbed.txt`](https://raw.githubusercontent.com/cometbft/cometbft/v0.38.x/docs/qa/img38/200nodes/v038_report_tabbed.txt)). The X axis (`c`) is the number of connections created by the load runner process to the target node. The Y axis (`r`) is the rate or number of transactions issued per second. diff --git a/cometbft/v0.38/docs/qa/TMCore-QA-34.mdx b/cometbft/v0.38/docs/qa/TMCore-QA-34.mdx index 5313047b..4aebd68d 100644 --- a/cometbft/v0.38/docs/qa/TMCore-QA-34.mdx +++ b/cometbft/v0.38/docs/qa/TMCore-QA-34.mdx @@ -18,7 +18,7 @@ from being stable: the load runner tries to produce slightly more transactions t be processed by the testnet. The following table summarizes the results for v0.34.x for the different experiments -(extracted from file [`v034_report_tabbed.txt`](https://github.com/cometbft/cometbft/blob/main/docs/references/qa//cometbft/v0.38/docs/qa/img34/v034_report_tabbed.txt)). +(extracted from file [`v034_report_tabbed.txt`](https://raw.githubusercontent.com/cometbft/cometbft/v0.38.x/docs/qa/img34/v034_report_tabbed.txt)). The X axis of this table is `c`, the number of connections created by the load runner process to the target node. The Y axis of this table is `r`, the rate or number of transactions issued per second. diff --git a/cometbft/v0.38/docs/qa/TMCore-QA-37.mdx b/cometbft/v0.38/docs/qa/TMCore-QA-37.mdx index ec543c6f..3b6358ee 100644 --- a/cometbft/v0.38/docs/qa/TMCore-QA-37.mdx +++ b/cometbft/v0.38/docs/qa/TMCore-QA-37.mdx @@ -36,7 +36,7 @@ For further details, see [this paragraph](/cometbft/v0.38/docs/qa/TMCore-QA-34#f in the baseline version. The following table summarizes the results for v0.37.x for the different experiments -(extracted from file [`v037_report_tabbed.txt`](https://github.com/cometbft/cometbft/blob/main/docs/references/qa//cometbft/v0.38/docs/qa/img37/200nodes_tm037/v037_report_tabbed.txt)). +(extracted from file [`v037_report_tabbed.txt`](https://raw.githubusercontent.com/cometbft/cometbft/v0.38.x/docs/qa/img37/200nodes_tm037/v037_report_tabbed.txt)). The X axis of this table is `c`, the number of connections created by the load runner process to the target node. The Y axis of this table is `r`, the rate or number of transactions issued per second. diff --git a/evm/v0.5.0/documentation/smart-contracts/predeployed-contracts/permit2.mdx b/evm/v0.5.0/documentation/smart-contracts/predeployed-contracts/permit2.mdx index 683d96c6..167eaef7 100644 --- a/evm/v0.5.0/documentation/smart-contracts/predeployed-contracts/permit2.mdx +++ b/evm/v0.5.0/documentation/smart-contracts/predeployed-contracts/permit2.mdx @@ -405,11 +405,11 @@ class PaymentProcessor { - [Permit2 SDK](https://github.com/Uniswap/permit2-sdk) - Official TypeScript SDK - [Permit2 Universal Router](https://github.com/Uniswap/universal-router) - Integration example -- [Permit2 Periphery](https://github.com/Uniswap/permit2-periphery) - Helper contracts +- Permit2 Periphery - Helper contracts ## Further Reading - [Permit2 Introduction Blog](https://blog.uniswap.org/permit2-and-universal-router) - [Permit2 GitHub Repository](https://github.com/Uniswap/permit2) - [EIP-2612: Permit Extension](https://eips.ethereum.org/EIPS/eip-2612) -- [Security Best Practices](https://github.com/Uniswap/permit2/blob/main/docs/security.md) \ No newline at end of file +- Security Best Practices \ No newline at end of file diff --git a/hub/v25/governance/formatting.mdx b/hub/v25/governance/formatting.mdx index c763ab75..b8c1e885 100644 --- a/hub/v25/governance/formatting.mdx +++ b/hub/v25/governance/formatting.mdx @@ -116,7 +116,7 @@ that changes more parameters than was intended. The parameters that you do not w ### Real example -This example is 'real', because it was put on-chain using the Theta testnet and can be seen in the block explorer [here](https://explorer.theta-testnet.polypore.xyz/proposals/87). +This example is 'real', because it was put on-chain using the Theta testnet and can be seen. Not all explorers will show the proposed parameter changes that are coded into the proposal, so ensure that you verify that the description aligns with what the governance proposal is programmed to enact. If the description says that a certain parameter will be increased, it should also be programmed to do that, but it's possible that that's not the case (accidentally or otherwise). diff --git a/hub/v25/governance/proposal-types/community-pool-spend.mdx b/hub/v25/governance/proposal-types/community-pool-spend.mdx index 71afce13..8c18cdb5 100644 --- a/hub/v25/governance/proposal-types/community-pool-spend.mdx +++ b/hub/v25/governance/proposal-types/community-pool-spend.mdx @@ -27,7 +27,7 @@ You may directly query the Cosmos Hub 4 for the balance of the Community Pool: `gaiad q distribution community-pool --chain-id cosmoshub-4 --node ` -Alternatively, popular Cosmos explorers such as [Big Dipper](https://cosmos.bigdipper.live) and [Mintscan](https://www.mintscan.io/cosmos) display the ongoing Community Pool balance. +Alternatively, popular Cosmos explorers such as [Mintscan](https://www.mintscan.io/cosmos) display the ongoing Community Pool balance. ### How can funds from the Community Pool be spent? diff --git a/hub/v25/resources/archives.mdx b/hub/v25/resources/archives.mdx index 38694244..67fb996e 100644 --- a/hub/v25/resources/archives.mdx +++ b/hub/v25/resources/archives.mdx @@ -9,7 +9,7 @@ With each breaking upgrade of the Cosmos Hub, the network is restarted at height As a result, the blocks of the previous networks are not downloaded by new clients (as they sync from the new genesis state), and may be deleted by existing full-nodes. -In an effort to maintain transparency, the interchain hosts archives of the previous versions of the Cosmos Hub network. These archives can be found [here](https://archive.interchain.io/). +Historical snapshots are available from community snapshot providers such as [Quicksync](https://quicksync.io/cosmos) and [Polkachu](https://polkachu.com/networks/cosmos). Always do your own research before trusting a third-party snapshot provider. If you would like to search explorers for previous hub data, these are some links where you can find the information: diff --git a/ibc/v10.1.x/migrations/sdk-to-v1.mdx b/ibc/v10.1.x/migrations/sdk-to-v1.mdx index f245d91d..fe82a9d2 100644 --- a/ibc/v10.1.x/migrations/sdk-to-v1.mdx +++ b/ibc/v10.1.x/migrations/sdk-to-v1.mdx @@ -46,7 +46,7 @@ Both in-place store migrations and genesis migrations will: * prune all solo machine consensus states * prune all expired tendermint consensus states -Chains must set a new connection parameter during either in place store migrations or genesis migration. The new parameter, max expected block time, is used to enforce packet processing delays on the receiving end of an IBC packet flow. Checkout the [docs](https://github.com/cosmos/ibc-go/blob/release/v1.0.x/ibc/proto-docs.md#params-2) for more information. +Chains must set a new connection parameter during either in place store migrations or genesis migration. The new parameter, max expected block time, is used to enforce packet processing delays on the receiving end of an IBC packet flow. Checkout the [docs](https://github.com/cosmos/ibc-go/blob/release/v1.0.x/docs/ibc/proto-docs.md#params-2) for more information. ### In-Place Store Migrations @@ -58,7 +58,7 @@ Ex: app.UpgradeKeeper.SetUpgradeHandler("my-upgrade-proposal", func(ctx sdk.Context, _ upgradetypes.Plan, _ module.VersionMap) (module.VersionMap, error) { / set max expected block time parameter. Replace the default with your expected value - / https://github.com/cosmos/ibc-go/blob/release/v1.0.x/ibc/proto-docs.md#params-2 + / https://github.com/cosmos/ibc-go/blob/release/v1.0.x/docs/ibc/proto-docs.md#params-2 app.IBCKeeper.ConnectionKeeper.SetParams(ctx, ibcconnectiontypes.DefaultParams()) fromVM := map[string]uint64{ ... / other modules @@ -86,7 +86,7 @@ import ( / add in migrate cmd function / expectedTimePerBlock is a new connection parameter -/ https://github.com/cosmos/ibc-go/blob/release/v1.0.x/ibc/proto-docs.md#params-2 +/ https://github.com/cosmos/ibc-go/blob/release/v1.0.x/docs/ibc/proto-docs.md#params-2 newGenState, err = ibcv100.MigrateGenesis(newGenState, clientCtx, *genDoc, expectedTimePerBlock) if err != nil { return err diff --git a/ibc/v4.6.x/ibc/proto-docs.mdx b/ibc/v4.6.x/ibc/proto-docs.mdx index c0882d05..d6f7f3d0 100644 --- a/ibc/v4.6.x/ibc/proto-docs.mdx +++ b/ibc/v4.6.x/ibc/proto-docs.mdx @@ -3,4 +3,4 @@ title: Protobuf Documentation description: See ibc-go v4.4.x Buf Protobuf documentation. --- -See [ibc-go v4.4.x Buf Protobuf documentation](https://github.com/cosmos/ibc-go/blob/release/v4.4.x/ibc/proto-docs.md). +See [ibc-go v4.4.x Buf Protobuf documentation](https://github.com/cosmos/ibc-go/blob/release/v4.4.x/docs/ibc/proto-docs.md). diff --git a/ibc/v4.6.x/migrations/sdk-to-v1.mdx b/ibc/v4.6.x/migrations/sdk-to-v1.mdx index 2ea8d2af..19cb7898 100644 --- a/ibc/v4.6.x/migrations/sdk-to-v1.mdx +++ b/ibc/v4.6.x/migrations/sdk-to-v1.mdx @@ -46,7 +46,7 @@ Both in-place store migrations and genesis migrations will: * prune all solo machine consensus states * prune all expired tendermint consensus states -Chains must set a new connection parameter during either in place store migrations or genesis migration. The new parameter, max expected block time, is used to enforce packet processing delays on the receiving end of an IBC packet flow. Checkout the [docs](https://github.com/cosmos/ibc-go/blob/release/v1.0.x/ibc/proto-docs.md#params-2) for more information. +Chains must set a new connection parameter during either in place store migrations or genesis migration. The new parameter, max expected block time, is used to enforce packet processing delays on the receiving end of an IBC packet flow. Checkout the [docs](https://github.com/cosmos/ibc-go/blob/release/v1.0.x/docs/ibc/proto-docs.md#params-2) for more information. ### In-Place Store Migrations @@ -58,7 +58,7 @@ Ex: app.UpgradeKeeper.SetUpgradeHandler("my-upgrade-proposal", func(ctx sdk.Context, _ upgradetypes.Plan, _ module.VersionMap) (module.VersionMap, error) { / set max expected block time parameter. Replace the default with your expected value - / https://github.com/cosmos/ibc-go/blob/release/v1.0.x/ibc/proto-docs.md#params-2 + / https://github.com/cosmos/ibc-go/blob/release/v1.0.x/docs/ibc/proto-docs.md#params-2 app.IBCKeeper.ConnectionKeeper.SetParams(ctx, ibcconnectiontypes.DefaultParams()) fromVM := map[string]uint64{ ... / other modules @@ -86,7 +86,7 @@ import ( / add in migrate cmd function / expectedTimePerBlock is a new connection parameter -/ https://github.com/cosmos/ibc-go/blob/release/v1.0.x/ibc/proto-docs.md#params-2 +/ https://github.com/cosmos/ibc-go/blob/release/v1.0.x/docs/ibc/proto-docs.md#params-2 newGenState, err = ibcv100.MigrateGenesis(newGenState, clientCtx, *genDoc, expectedTimePerBlock) if err != nil { return err diff --git a/ibc/v5.4.x/migrations/sdk-to-v1.mdx b/ibc/v5.4.x/migrations/sdk-to-v1.mdx index f78708c1..5559d092 100644 --- a/ibc/v5.4.x/migrations/sdk-to-v1.mdx +++ b/ibc/v5.4.x/migrations/sdk-to-v1.mdx @@ -46,7 +46,7 @@ Both in-place store migrations and genesis migrations will: * prune all solo machine consensus states * prune all expired tendermint consensus states -Chains must set a new connection parameter during either in place store migrations or genesis migration. The new parameter, max expected block time, is used to enforce packet processing delays on the receiving end of an IBC packet flow. Checkout the [docs](https://github.com/cosmos/ibc-go/blob/release/v1.0.x/ibc/proto-docs.md#params-2) for more information. +Chains must set a new connection parameter during either in place store migrations or genesis migration. The new parameter, max expected block time, is used to enforce packet processing delays on the receiving end of an IBC packet flow. Checkout the [docs](https://github.com/cosmos/ibc-go/blob/release/v1.0.x/docs/ibc/proto-docs.md#params-2) for more information. ### In-Place Store Migrations @@ -58,7 +58,7 @@ Ex: app.UpgradeKeeper.SetUpgradeHandler("my-upgrade-proposal", func(ctx sdk.Context, _ upgradetypes.Plan, _ module.VersionMap) (module.VersionMap, error) { / set max expected block time parameter. Replace the default with your expected value - / https://github.com/cosmos/ibc-go/blob/release/v1.0.x/ibc/proto-docs.md#params-2 + / https://github.com/cosmos/ibc-go/blob/release/v1.0.x/docs/ibc/proto-docs.md#params-2 app.IBCKeeper.ConnectionKeeper.SetParams(ctx, ibcconnectiontypes.DefaultParams()) fromVM := map[string]uint64{ ... / other modules @@ -86,7 +86,7 @@ import ( / add in migrate cmd function / expectedTimePerBlock is a new connection parameter -/ https://github.com/cosmos/ibc-go/blob/release/v1.0.x/ibc/proto-docs.md#params-2 +/ https://github.com/cosmos/ibc-go/blob/release/v1.0.x/docs/ibc/proto-docs.md#params-2 newGenState, err = ibcv100.MigrateGenesis(newGenState, clientCtx, *genDoc, expectedTimePerBlock) if err != nil { return err diff --git a/ibc/v6.3.x/ibc/proto-docs.mdx b/ibc/v6.3.x/ibc/proto-docs.mdx index ccb53f0b..75a9b9c5 100644 --- a/ibc/v6.3.x/ibc/proto-docs.mdx +++ b/ibc/v6.3.x/ibc/proto-docs.mdx @@ -3,4 +3,4 @@ title: Protobuf Documentation description: See ibc-go v6.2.x Buf Protobuf documentation. --- -See [ibc-go v6.2.x Buf Protobuf documentation](https://github.com/cosmos/ibc-go/blob/release/v6.2.x/ibc/proto-docs.md). +See [ibc-go v6.2.x Buf Protobuf documentation](https://github.com/cosmos/ibc-go/blob/release/v6.2.x/docs/ibc/proto-docs.md). diff --git a/ibc/v6.3.x/migrations/sdk-to-v1.mdx b/ibc/v6.3.x/migrations/sdk-to-v1.mdx index 622b1de8..1a19c3e3 100644 --- a/ibc/v6.3.x/migrations/sdk-to-v1.mdx +++ b/ibc/v6.3.x/migrations/sdk-to-v1.mdx @@ -46,7 +46,7 @@ Both in-place store migrations and genesis migrations will: * prune all solo machine consensus states * prune all expired tendermint consensus states -Chains must set a new connection parameter during either in place store migrations or genesis migration. The new parameter, max expected block time, is used to enforce packet processing delays on the receiving end of an IBC packet flow. Checkout the [docs](https://github.com/cosmos/ibc-go/blob/release/v1.0.x/ibc/proto-docs.md#params-2) for more information. +Chains must set a new connection parameter during either in place store migrations or genesis migration. The new parameter, max expected block time, is used to enforce packet processing delays on the receiving end of an IBC packet flow. Checkout the [docs](https://github.com/cosmos/ibc-go/blob/release/v1.0.x/docs/ibc/proto-docs.md#params-2) for more information. ### In-Place Store Migrations @@ -58,7 +58,7 @@ Ex: app.UpgradeKeeper.SetUpgradeHandler("my-upgrade-proposal", func(ctx sdk.Context, _ upgradetypes.Plan, _ module.VersionMap) (module.VersionMap, error) { / set max expected block time parameter. Replace the default with your expected value - / https://github.com/cosmos/ibc-go/blob/release/v1.0.x/ibc/proto-docs.md#params-2 + / https://github.com/cosmos/ibc-go/blob/release/v1.0.x/docs/ibc/proto-docs.md#params-2 app.IBCKeeper.ConnectionKeeper.SetParams(ctx, ibcconnectiontypes.DefaultParams()) fromVM := map[string]uint64{ ... / other modules @@ -86,7 +86,7 @@ import ( / add in migrate cmd function / expectedTimePerBlock is a new connection parameter -/ https://github.com/cosmos/ibc-go/blob/release/v1.0.x/ibc/proto-docs.md#params-2 +/ https://github.com/cosmos/ibc-go/blob/release/v1.0.x/docs/ibc/proto-docs.md#params-2 newGenState, err = ibcv100.MigrateGenesis(newGenState, clientCtx, *genDoc, expectedTimePerBlock) if err != nil { return err diff --git a/ibc/v7.8.x/middleware/ics29-fee/fee-distribution.mdx b/ibc/v7.8.x/middleware/ics29-fee/fee-distribution.mdx index d9dcb304..a3fa26f6 100644 --- a/ibc/v7.8.x/middleware/ics29-fee/fee-distribution.mdx +++ b/ibc/v7.8.x/middleware/ics29-fee/fee-distribution.mdx @@ -95,8 +95,8 @@ type MsgRegisterPayee struct { > > - `PortId` is invalid (see [24-host naming requirements](https://github.com/cosmos/ibc/blob/master/spec/core/ics-024-host-requirements/README.md#paths-identifiers-separators). > - `ChannelId` is invalid (see [24-host naming requirements](https://github.com/cosmos/ibc/blob/master/spec/core/ics-024-host-requirements/README.md#paths-identifiers-separators)). -> - `Relayer` is an invalid address (see [Cosmos SDK Addresses](https://github.com/cosmos/cosmos-sdk/blob/main/docs/learn/beginner/03-accounts.md#addresses)). -> - `Payee` is an invalid address (see [Cosmos SDK Addresses](https://github.com/cosmos/cosmos-sdk/blob/main/docs/learn/beginner/03-accounts.md#addresses)). +> - `Relayer` is an invalid address (see [Cosmos SDK Addresses](https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/learn/beginner/03-accounts.md#addresses)). +> - `Payee` is an invalid address (see [Cosmos SDK Addresses](https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/learn/beginner/03-accounts.md#addresses)). See below for an example CLI command: diff --git a/ibc/v7.8.x/migrations/sdk-to-v1.mdx b/ibc/v7.8.x/migrations/sdk-to-v1.mdx index bfb15cab..a271ae98 100644 --- a/ibc/v7.8.x/migrations/sdk-to-v1.mdx +++ b/ibc/v7.8.x/migrations/sdk-to-v1.mdx @@ -46,7 +46,7 @@ Both in-place store migrations and genesis migrations will: * prune all solo machine consensus states * prune all expired tendermint consensus states -Chains must set a new connection parameter during either in place store migrations or genesis migration. The new parameter, max expected block time, is used to enforce packet processing delays on the receiving end of an IBC packet flow. Checkout the [docs](https://github.com/cosmos/ibc-go/blob/release/v1.0.x/ibc/proto-docs.md#params-2) for more information. +Chains must set a new connection parameter during either in place store migrations or genesis migration. The new parameter, max expected block time, is used to enforce packet processing delays on the receiving end of an IBC packet flow. Checkout the [docs](https://github.com/cosmos/ibc-go/blob/release/v1.0.x/docs/ibc/proto-docs.md#params-2) for more information. ### In-Place Store Migrations @@ -58,7 +58,7 @@ Ex: app.UpgradeKeeper.SetUpgradeHandler("my-upgrade-proposal", func(ctx sdk.Context, _ upgradetypes.Plan, _ module.VersionMap) (module.VersionMap, error) { / set max expected block time parameter. Replace the default with your expected value - / https://github.com/cosmos/ibc-go/blob/release/v1.0.x/ibc/proto-docs.md#params-2 + / https://github.com/cosmos/ibc-go/blob/release/v1.0.x/docs/ibc/proto-docs.md#params-2 app.IBCKeeper.ConnectionKeeper.SetParams(ctx, ibcconnectiontypes.DefaultParams()) fromVM := map[string]uint64{ ... / other modules @@ -86,7 +86,7 @@ import ( / add in migrate cmd function / expectedTimePerBlock is a new connection parameter -/ https://github.com/cosmos/ibc-go/blob/release/v1.0.x/ibc/proto-docs.md#params-2 +/ https://github.com/cosmos/ibc-go/blob/release/v1.0.x/docs/ibc/proto-docs.md#params-2 newGenState, err = ibcv100.MigrateGenesis(newGenState, clientCtx, *genDoc, expectedTimePerBlock) if err != nil { return err diff --git a/ibc/v8.5.x/migrations/sdk-to-v1.mdx b/ibc/v8.5.x/migrations/sdk-to-v1.mdx index 67373b0f..8750c700 100644 --- a/ibc/v8.5.x/migrations/sdk-to-v1.mdx +++ b/ibc/v8.5.x/migrations/sdk-to-v1.mdx @@ -46,7 +46,7 @@ Both in-place store migrations and genesis migrations will: * prune all solo machine consensus states * prune all expired tendermint consensus states -Chains must set a new connection parameter during either in place store migrations or genesis migration. The new parameter, max expected block time, is used to enforce packet processing delays on the receiving end of an IBC packet flow. Checkout the [docs](https://github.com/cosmos/ibc-go/blob/release/v1.0.x/ibc/proto-docs.md#params-2) for more information. +Chains must set a new connection parameter during either in place store migrations or genesis migration. The new parameter, max expected block time, is used to enforce packet processing delays on the receiving end of an IBC packet flow. Checkout the [docs](https://github.com/cosmos/ibc-go/blob/release/v1.0.x/docs/ibc/proto-docs.md#params-2) for more information. ### In-Place Store Migrations @@ -58,7 +58,7 @@ Ex: app.UpgradeKeeper.SetUpgradeHandler("my-upgrade-proposal", func(ctx sdk.Context, _ upgradetypes.Plan, _ module.VersionMap) (module.VersionMap, error) { / set max expected block time parameter. Replace the default with your expected value - / https://github.com/cosmos/ibc-go/blob/release/v1.0.x/ibc/proto-docs.md#params-2 + / https://github.com/cosmos/ibc-go/blob/release/v1.0.x/docs/ibc/proto-docs.md#params-2 app.IBCKeeper.ConnectionKeeper.SetParams(ctx, ibcconnectiontypes.DefaultParams()) fromVM := map[string]uint64{ ... / other modules @@ -86,7 +86,7 @@ import ( / add in migrate cmd function / expectedTimePerBlock is a new connection parameter -/ https://github.com/cosmos/ibc-go/blob/release/v1.0.x/ibc/proto-docs.md#params-2 +/ https://github.com/cosmos/ibc-go/blob/release/v1.0.x/docs/ibc/proto-docs.md#params-2 newGenState, err = ibcv100.MigrateGenesis(newGenState, clientCtx, *genDoc, expectedTimePerBlock) if err != nil { return err diff --git a/sdk/next/changelog/release-notes.mdx b/sdk/next/changelog/release-notes.mdx index b2a091d2..a52dedb1 100644 --- a/sdk/next/changelog/release-notes.mdx +++ b/sdk/next/changelog/release-notes.mdx @@ -325,7 +325,7 @@ mode: "wide" - (core) [#14860](https://github.com/cosmos/cosmos-sdk/pull/14860) Add `Precommit` and `PrepareCheckState` AppModule callbacks. - (x/gov) [#14720](https://github.com/cosmos/cosmos-sdk/pull/14720) Upstream expedited proposals from Osmosis. - (cli) [#14659](https://github.com/cosmos/cosmos-sdk/pull/14659) Added ability to query blocks by events with queries directly passed to Tendermint, which will allow for full query operator support, e.g. `>`. -- (x/auth) [#14650](https://github.com/cosmos/cosmos-sdk/pull/14650) Add Textual SignModeHandler. Enable `SIGN_MODE_TEXTUAL` by following the [UPGRADING.mdx](https://github.com/cosmos/cosmos-sdk/blob/main/UPGRADING.mdx) instructions. +- (x/auth) [#14650](https://github.com/cosmos/cosmos-sdk/pull/14650) Add Textual SignModeHandler. Enable `SIGN_MODE_TEXTUAL` by following the [UPGRADING.mdx](https://github.com/cosmos/cosmos-sdk/blob/main/UPGRADING.md) instructions. - (x/crisis) [#14588](https://github.com/cosmos/cosmos-sdk/pull/14588) Use CacheContext() in AssertInvariants(). - (mempool) [#14484](https://github.com/cosmos/cosmos-sdk/pull/14484) Add priority nonce mempool option for transaction replacement. - (query) [#14468](https://github.com/cosmos/cosmos-sdk/pull/14468) Implement pagination for collections. diff --git a/sdk/v0.47/build/architecture/adr-016-validator-consensus-key-rotation.mdx b/sdk/v0.47/build/architecture/adr-016-validator-consensus-key-rotation.mdx index f8e5161f..c69d3ef2 100644 --- a/sdk/v0.47/build/architecture/adr-016-validator-consensus-key-rotation.mdx +++ b/sdk/v0.47/build/architecture/adr-016-validator-consensus-key-rotation.mdx @@ -116,7 +116,7 @@ Proposed ### Positive * Validators can immediately or periodically rotate their consensus key to have better security policy -* improved security against Long-Range attacks ([Link](https://nearprotocol.com/blog/long-range-attacks-and-a-new-fork-choice-rule)) given a validator throws away the old consensus key(s) +* improved security against Long-Range attacks given a validator throws away the old consensus key(s) ### Negative diff --git a/sdk/v0.47/build/architecture/adr-033-protobuf-inter-module-comm.mdx b/sdk/v0.47/build/architecture/adr-033-protobuf-inter-module-comm.mdx index 486c4de6..dd8f7c9a 100644 --- a/sdk/v0.47/build/architecture/adr-033-protobuf-inter-module-comm.mdx +++ b/sdk/v0.47/build/architecture/adr-033-protobuf-inter-module-comm.mdx @@ -452,4 +452,4 @@ replacing `Keeper` interfaces altogether. * [ADR 031](/sdk/v0.47/build/architecture/adr-031-msg-service) * [ADR 028](/sdk/v0.47/build/architecture/adr-028-public-key-addresses) * [ADR 030 draft](https://github.com/cosmos/cosmos-sdk/pull/7105) -* [Object-Capability Model](https://docs.network.com/main/core/ocap) +* [Object-Capability Model](/sdk/v0.47/learn/advanced/ocap) diff --git a/sdk/v0.47/build/architecture/adr-040-storage-and-smt-state-commitments.mdx b/sdk/v0.47/build/architecture/adr-040-storage-and-smt-state-commitments.mdx index 2d0e4683..392d2867 100644 --- a/sdk/v0.47/build/architecture/adr-040-storage-and-smt-state-commitments.mdx +++ b/sdk/v0.47/build/architecture/adr-040-storage-and-smt-state-commitments.mdx @@ -26,7 +26,7 @@ In the current design, IAVL is used for both data storage and as a Merkle Tree f * Each edge traversal requires a DB query. * Creating snapshots is [expensive](https://github.com/cosmos/cosmos-sdk/issues/7215#issuecomment-684804950). It takes about 30 seconds to export less than 100 MB of state (as of March 2020). * Updates in IAVL may trigger tree reorganization and possible O(log(n)) hashes re-computation, which can become a CPU bottleneck. -* The node structure is pretty expensive - it contains a standard tree node elements (key, value, left and right element) and additional metadata such as height, version (which is not required by the Cosmos SDK). The entire node is hashed, and that hash is used as the key in the underlying database, [ref](https://github.com/cosmos/iavl/blob/master/docs/node/03-node.md). +* The node structure is pretty expensive - it contains a standard tree node elements (key, value, left and right element) and additional metadata such as height, version (which is not required by the Cosmos SDK). The entire node is hashed, and that hash is used as the key in the underlying database, [ref](https://github.com/cosmos/iavl/blob/master/docs/node/node.md). Moreover, the IAVL project lacks support and a maintainer and we already see better and well-established alternatives. Instead of optimizing the IAVL, we are looking into other solutions for both storage and state commitments. @@ -293,5 +293,5 @@ We were discussing use case where modules can use a support database, which is n * Facebook Diem (Libra) SMT [design](https://developers.diem.com/papers/jellyfish-merkle-tree/2021-01-14.pdf) * [Trillian Revocation Transparency](https://github.com/google/trillian/blob/master/docs/papers/RevocationTransparency.pdf), [Trillian Verifiable Data Structures](https://github.com/google/trillian/blob/master/docs/papers/VerifiableDataStructures.pdf). * Design and implementation [discussion](https://github.com/cosmos/cosmos-sdk/discussions/8297). -* [How to Upgrade IBC Chains and their Clients](https://github.com/cosmos/ibc-go/blob/main/ibc/upgrades/quick-guide.md) +* [How to Upgrade IBC Chains and their Clients](https://github.com/cosmos/ibc-go/blob/main/docs/docs/01-ibc/05-upgrades/01-quick-guide.md) * [ADR-40 Effect on IBC](https://github.com/cosmos/ibc-go/discussions/256) diff --git a/sdk/v0.47/build/architecture/adr-049-state-sync-hooks.mdx b/sdk/v0.47/build/architecture/adr-049-state-sync-hooks.mdx index 6553dd4c..e684d519 100644 --- a/sdk/v0.47/build/architecture/adr-049-state-sync-hooks.mdx +++ b/sdk/v0.47/build/architecture/adr-049-state-sync-hooks.mdx @@ -194,4 +194,4 @@ Test cases for an implementation are mandatory for ADRs that are affecting conse * [Link](https://github.com/cosmos/cosmos-sdk/pull/10961) * [Link](https://github.com/cosmos/cosmos-sdk/issues/7340) -* [Link](https://hackmd.io/gJoyev6DSmqqkO667WQlGw) + diff --git a/sdk/v0.47/build/architecture/adr-054-semver-compatible-modules.mdx b/sdk/v0.47/build/architecture/adr-054-semver-compatible-modules.mdx index 9b9521cc..b04e8c93 100644 --- a/sdk/v0.47/build/architecture/adr-054-semver-compatible-modules.mdx +++ b/sdk/v0.47/build/architecture/adr-054-semver-compatible-modules.mdx @@ -476,7 +476,7 @@ languages, possibly executed within a WASM VM. ### Minor API Revisions To declare minor API revisions of proto files, we propose the following guidelines (which were already documented -in [cosmos.app.v1alpha module options](https://github.com/cosmos/cosmos-sdk/blob/v0.47/proto/cosmos/app/v1alpha1/module.proto)): +in [cosmos.app.v1alpha module options](https://github.com/cosmos/cosmos-sdk/blob/v0.47.12/proto/cosmos/app/v1alpha1/module.proto)): * proto packages which are revised from their initial version (considered revision `0`) should include a `package` * comment in some .proto file containing the test `Revision N` at the start of a comment line where `N` is the current diff --git a/sdk/v0.47/build/architecture/adr-059-test-scopes.mdx b/sdk/v0.47/build/architecture/adr-059-test-scopes.mdx index 903c8c2a..0b68197e 100644 --- a/sdk/v0.47/build/architecture/adr-059-test-scopes.mdx +++ b/sdk/v0.47/build/architecture/adr-059-test-scopes.mdx @@ -61,7 +61,7 @@ Tests which exercise a whole module's function with dependencies mocked, are *jo These are almost like integration tests in that they exercise many things together but still use mocks. -Example 1 journey vs illustrative tests - [depinject's BDD style tests](https://github.com/cosmos/cosmos-sdk/blob/main/depinject/features/bindings.feature), show how we can +Example 1 journey vs illustrative tests - depinject's BDD style tests, show how we can rapidly build up many illustrative cases demonstrating behavioral rules without [very much code](https://github.com/cosmos/cosmos-sdk/blob/main/depinject/binding_test.go) while maintaining high level readability. Example 2 [depinject table driven tests](https://github.com/cosmos/cosmos-sdk/blob/main/depinject/provider_desc_test.go) @@ -103,7 +103,7 @@ exercises [HandleEquivocationEvidence](https://github.com/cosmos/cosmos-sdk/blob keeper. Example 3 - Integration suite app configurations may also be specified via golang (not -YAML as above) [statically](https://github.com/cosmos/cosmos-sdk/blob/main/x/nft/testutil/app_config.go) or [dynamically](https://github.com/cosmos/cosmos-sdk/blob/8c23f6f957d1c0bedd314806d1ac65bea59b084c/tests/integration/bank/keeper/keeper_test.go#L129-L134). +YAML as above) statically or [dynamically](https://github.com/cosmos/cosmos-sdk/blob/8c23f6f957d1c0bedd314806d1ac65bea59b084c/tests/integration/bank/keeper/keeper_test.go#L129-L134). #### Limitations @@ -141,9 +141,9 @@ managing their life cycle. #### Limitations -* [A success](https://github.com/cosmos/cosmos-sdk/runs/7606931983?check_suite_focus=true) may take a long time to run, 7-10 minutes per simulation in CI. -* [Timeouts](https://github.com/cosmos/cosmos-sdk/runs/7606932295?check_suite_focus=true) sometimes occur on apparent successes without any indication why. -* Useful error messages not provided on [failure](https://github.com/cosmos/cosmos-sdk/runs/7606932548?check_suite_focus=true) from CI, requiring a developer to run +* A success may take a long time to run, 7-10 minutes per simulation in CI. +* Timeouts sometimes occur on apparent successes without any indication why. +* Useful error messages not provided on failure from CI, requiring a developer to run the simulation locally to reproduce. ### E2E tests diff --git a/sdk/v0.47/build/migrations/upgrading.mdx b/sdk/v0.47/build/migrations/upgrading.mdx index 6b66148f..e68c92f1 100644 --- a/sdk/v0.47/build/migrations/upgrading.mdx +++ b/sdk/v0.47/build/migrations/upgrading.mdx @@ -401,7 +401,7 @@ In case a module does not follow the standard message path, (e.g. IBC), it is ad The `params` module was deprecated since v0.46. The Cosmos SDK has migrated away from `x/params` for its own modules. Cosmos SDK modules now store their parameters directly in its repective modules. -The `params` module will be removed in `v0.48`, as mentioned [in v0.46 release](https://github.com/cosmos/cosmos-sdk/blob/v0.46.1/UPGRADING.mdx#xparams). It is strongly encouraged to migrate away from `x/params` before `v0.48`. +The `params` module will be removed in `v0.48`, as mentioned [in v0.46 release](https://github.com/cosmos/cosmos-sdk/blob/v0.46.1/UPGRADING.md#xparams). It is strongly encouraged to migrate away from `x/params` before `v0.48`. When performing a chain migration, the params table must be initizalied manually. This was done in the modules keepers in previous versions. Have a look at `simapp.RegisterUpgradeHandlers()` for an example. diff --git a/sdk/v0.47/build/spec/addresses/bech32.mdx b/sdk/v0.47/build/spec/addresses/bech32.mdx index ac52b2cf..73091371 100644 --- a/sdk/v0.47/build/spec/addresses/bech32.mdx +++ b/sdk/v0.47/build/spec/addresses/bech32.mdx @@ -20,4 +20,4 @@ While all user facing interfaces to Cosmos software should exposed Bech32 interf To covert between other binary representation of addresses and keys, it is important to first apply the Amino encoding process before Bech32 encoding. -A complete implementation of the Amino serialization format is unnecessary in most cases. Simply prepending bytes from this [table](https://github.com/cometbft/cometbft/blob/main/spec/blockchain/05-encoding.md) to the byte string payload before Bech32 encoding will sufficient for compatible representation. +A complete implementation of the Amino serialization format is unnecessary in most cases. Simply prepending bytes from this [table](https://github.com/cometbft/cometbft/blob/main/spec/blockchain/encoding.md) to the byte string payload before Bech32 encoding will sufficient for compatible representation. diff --git a/sdk/v0.47/build/tooling/cosmovisor.mdx b/sdk/v0.47/build/tooling/cosmovisor.mdx index 36363fd0..da654847 100644 --- a/sdk/v0.47/build/tooling/cosmovisor.mdx +++ b/sdk/v0.47/build/tooling/cosmovisor.mdx @@ -320,7 +320,7 @@ cosmovisor run start Update app to the latest version (e.g. v0.45). -Next, we can add a migration - which is defined using `x/upgrade` [upgrade plan](https://github.com/cosmos/cosmos-sdk/blob/main/docs/advanced/13-upgrade.md) (you may refer to a past version if you are using an older Cosmos SDK release). In a migration we can do any deterministic state change. +Next, we can add a migration - which is defined using `x/upgrade` [upgrade plan](https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/build/building-apps/03-app-upgrade.md) (you may refer to a past version if you are using an older Cosmos SDK release). In a migration we can do any deterministic state change. Build the new version `simd` binary: diff --git a/sdk/v0.47/build/tooling/hubl.mdx b/sdk/v0.47/build/tooling/hubl.mdx index f7b193ca..70bc5529 100644 --- a/sdk/v0.47/build/tooling/hubl.mdx +++ b/sdk/v0.47/build/tooling/hubl.mdx @@ -3,7 +3,7 @@ title: Hubl --- `Hubl` is a tool that allows you to query any Cosmos SDK based blockchain. -It takes advantage of the new [AutoCLI](https://pkg.go.dev/github.com/cosmos/cosmos-sdk/client/v2@v2.0.0-20220916140313-c5245716b516/cli) feature {/* TODO replace with AutoCLI docs */} of the Cosmos SDK. +It takes advantage of the new [AutoCLI](https://pkg.go.dev/github.com/cosmos/cosmos-sdk/client/v2) feature {/* TODO replace with AutoCLI docs */} of the Cosmos SDK. ## Installation diff --git a/sdk/v0.47/learn/intro/overview.mdx b/sdk/v0.47/learn/intro/overview.mdx index 5939abbe..4968e3e0 100644 --- a/sdk/v0.47/learn/intro/overview.mdx +++ b/sdk/v0.47/learn/intro/overview.mdx @@ -26,4 +26,4 @@ The Cosmos SDK is the most advanced framework for building custom application-sp ## Getting started with the Cosmos SDK * Learn more about the [architecture of a Cosmos SDK application](/sdk/v0.47/learn/intro/sdk-app-architecture) -* Learn how to build an application-specific blockchain from scratch with the [Cosmos SDK Tutorial](https://cosmos.network/docs/tutorial) +* Learn how to build an application-specific blockchain from scratch with the [Cosmos SDK Tutorial](https://tutorials.cosmos.network) diff --git a/sdk/v0.47/user/run-node/keyring.mdx b/sdk/v0.47/user/run-node/keyring.mdx index fb671aec..c183b444 100644 --- a/sdk/v0.47/user/run-node/keyring.mdx +++ b/sdk/v0.47/user/run-node/keyring.mdx @@ -27,7 +27,7 @@ is a list of the most popular operating systems and their respective passwords m * Windows: [Credentials Management API](https://docs.microsoft.com/en-us/windows/win32/secauthn/credentials-management) * GNU/Linux: * [libsecret](https://gitlab.gnome.org/GNOME/libsecret) - * [kwallet](https://api.kde.org/frameworks/kwallet/html/index.html) + * [kwallet](https://api.kde.org/kwallet-index.html) GNU/Linux distributions that use GNOME as default desktop environment typically come with [Seahorse](https://wiki.gnome.org/Apps/Seahorse). Users of KDE based distributions are @@ -89,7 +89,7 @@ one you may want to use specifically to encrypt the password store. The `kwallet` backend uses `KDE Wallet Manager`, which comes installed by default on the GNU/Linux distributions that ships KDE as default desktop environment. Please refer to -[KWallet Handbook](https://docs.kde.org/stable5/en/kdeutils/kwallet5/index.html) for more +[KWallet Handbook](https://userbase.kde.org/KDE_Wallet_Manager) for more information. ### The `test` backend diff --git a/sdk/v0.47/user/run-node/run-production.mdx b/sdk/v0.47/user/run-node/run-production.mdx index 812dab1d..acd44726 100644 --- a/sdk/v0.47/user/run-node/run-production.mdx +++ b/sdk/v0.47/user/run-node/run-production.mdx @@ -10,7 +10,7 @@ This section describes how to securely run a node in a public setting and/or on When operating a node, full node or validator, in production it is important to set your server up securely. -There are many different ways to secure a server and your node, the described steps here is one way. To see another way of setting up a server see the [run in production tutorial](https://tutorials.cosmos.network/hands-on-exercise/5-run-in-prod/1-overview.html). +There are many different ways to secure a server and your node, the described steps here is one way. To see another way of setting up a server see the [run in production tutorial](https://tutorials.cosmos.network/hands-on-exercise/4-run-in-prod). diff --git a/sdk/v0.50/build/abci/introduction.mdx b/sdk/v0.50/build/abci/introduction.mdx index 81147d00..fa6d03a7 100644 --- a/sdk/v0.50/build/abci/introduction.mdx +++ b/sdk/v0.50/build/abci/introduction.mdx @@ -25,7 +25,7 @@ The 5 methods introduced during ABCI 2.0 are: Based on their voting power, CometBFT chooses a block proposer and calls `PrepareProposal` on the block proposer's application (Cosmos SDK). The selected block proposer is responsible for collecting outstanding transactions from the mempool, adhering to the application's specifications. The application can enforce custom transaction ordering and incorporate additional transactions, potentially generated from vote extensions in the previous block. -To perform this manipulation on the application side, a custom handler must be implemented. By default, the Cosmos SDK provides `PrepareProposalHandler`, used in conjunction with an application specific mempool. A custom handler can be written by application developer, if a noop handler provided, all transactions are considered valid. Please see [this](https://github.com/fatal-fruit/abci-workshop) tutorial for more information on custom handlers. +To perform this manipulation on the application side, a custom handler must be implemented. By default, the Cosmos SDK provides `PrepareProposalHandler`, used in conjunction with an application specific mempool. A custom handler can be written by application developer, if a noop handler provided, all transactions are considered valid. Please see this tutorial for more information on custom handlers. Please note that vote extensions will only be available on the following height in which vote extensions are enabled. More information about vote extensions can be found [here](/sdk/v0.53/build/abci/vote-extensions). diff --git a/sdk/v0.50/build/architecture/adr-016-validator-consensus-key-rotation.mdx b/sdk/v0.50/build/architecture/adr-016-validator-consensus-key-rotation.mdx index f8e5161f..c69d3ef2 100644 --- a/sdk/v0.50/build/architecture/adr-016-validator-consensus-key-rotation.mdx +++ b/sdk/v0.50/build/architecture/adr-016-validator-consensus-key-rotation.mdx @@ -116,7 +116,7 @@ Proposed ### Positive * Validators can immediately or periodically rotate their consensus key to have better security policy -* improved security against Long-Range attacks ([Link](https://nearprotocol.com/blog/long-range-attacks-and-a-new-fork-choice-rule)) given a validator throws away the old consensus key(s) +* improved security against Long-Range attacks given a validator throws away the old consensus key(s) ### Negative diff --git a/sdk/v0.50/build/architecture/adr-033-protobuf-inter-module-comm.mdx b/sdk/v0.50/build/architecture/adr-033-protobuf-inter-module-comm.mdx index 140803f2..b3d38925 100644 --- a/sdk/v0.50/build/architecture/adr-033-protobuf-inter-module-comm.mdx +++ b/sdk/v0.50/build/architecture/adr-033-protobuf-inter-module-comm.mdx @@ -452,4 +452,4 @@ replacing `Keeper` interfaces altogether. * [ADR 031](/sdk/v0.50/build/architecture/adr-031-msg-service) * [ADR 028](/sdk/v0.50/build/architecture/adr-028-public-key-addresses) * [ADR 030 draft](https://github.com/cosmos/cosmos-sdk/pull/7105) -* [Object-Capability Model](https://docs.network.com/main/core/ocap) +* [Object-Capability Model](/sdk/v0.50/learn/advanced/ocap) diff --git a/sdk/v0.50/build/architecture/adr-040-storage-and-smt-state-commitments.mdx b/sdk/v0.50/build/architecture/adr-040-storage-and-smt-state-commitments.mdx index 8bfb4c48..392d2867 100644 --- a/sdk/v0.50/build/architecture/adr-040-storage-and-smt-state-commitments.mdx +++ b/sdk/v0.50/build/architecture/adr-040-storage-and-smt-state-commitments.mdx @@ -293,5 +293,5 @@ We were discussing use case where modules can use a support database, which is n * Facebook Diem (Libra) SMT [design](https://developers.diem.com/papers/jellyfish-merkle-tree/2021-01-14.pdf) * [Trillian Revocation Transparency](https://github.com/google/trillian/blob/master/docs/papers/RevocationTransparency.pdf), [Trillian Verifiable Data Structures](https://github.com/google/trillian/blob/master/docs/papers/VerifiableDataStructures.pdf). * Design and implementation [discussion](https://github.com/cosmos/cosmos-sdk/discussions/8297). -* [How to Upgrade IBC Chains and their Clients](https://github.com/cosmos/ibc-go/blob/main/ibc/upgrades/quick-guide.md) +* [How to Upgrade IBC Chains and their Clients](https://github.com/cosmos/ibc-go/blob/main/docs/docs/01-ibc/05-upgrades/01-quick-guide.md) * [ADR-40 Effect on IBC](https://github.com/cosmos/ibc-go/discussions/256) diff --git a/sdk/v0.50/build/architecture/adr-049-state-sync-hooks.mdx b/sdk/v0.50/build/architecture/adr-049-state-sync-hooks.mdx index 6553dd4c..e684d519 100644 --- a/sdk/v0.50/build/architecture/adr-049-state-sync-hooks.mdx +++ b/sdk/v0.50/build/architecture/adr-049-state-sync-hooks.mdx @@ -194,4 +194,4 @@ Test cases for an implementation are mandatory for ADRs that are affecting conse * [Link](https://github.com/cosmos/cosmos-sdk/pull/10961) * [Link](https://github.com/cosmos/cosmos-sdk/issues/7340) -* [Link](https://hackmd.io/gJoyev6DSmqqkO667WQlGw) + diff --git a/sdk/v0.50/build/architecture/adr-054-semver-compatible-modules.mdx b/sdk/v0.50/build/architecture/adr-054-semver-compatible-modules.mdx index bc9d9f18..516d8827 100644 --- a/sdk/v0.50/build/architecture/adr-054-semver-compatible-modules.mdx +++ b/sdk/v0.50/build/architecture/adr-054-semver-compatible-modules.mdx @@ -476,7 +476,7 @@ languages, possibly executed within a WASM VM. ### Minor API Revisions To declare minor API revisions of proto files, we propose the following guidelines (which were already documented -in [cosmos.app.v1alpha module options](https://github.com/cosmos/cosmos-sdk/blob/v0.50/proto/cosmos/app/v1alpha1/module.proto)): +in [cosmos.app.v1alpha module options](https://github.com/cosmos/cosmos-sdk/blob/v0.50.10/proto/cosmos/app/v1alpha1/module.proto)): * proto packages which are revised from their initial version (considered revision `0`) should include a `package` * comment in some .proto file containing the test `Revision N` at the start of a comment line where `N` is the current diff --git a/sdk/v0.50/build/architecture/adr-059-test-scopes.mdx b/sdk/v0.50/build/architecture/adr-059-test-scopes.mdx index 903c8c2a..0b68197e 100644 --- a/sdk/v0.50/build/architecture/adr-059-test-scopes.mdx +++ b/sdk/v0.50/build/architecture/adr-059-test-scopes.mdx @@ -61,7 +61,7 @@ Tests which exercise a whole module's function with dependencies mocked, are *jo These are almost like integration tests in that they exercise many things together but still use mocks. -Example 1 journey vs illustrative tests - [depinject's BDD style tests](https://github.com/cosmos/cosmos-sdk/blob/main/depinject/features/bindings.feature), show how we can +Example 1 journey vs illustrative tests - depinject's BDD style tests, show how we can rapidly build up many illustrative cases demonstrating behavioral rules without [very much code](https://github.com/cosmos/cosmos-sdk/blob/main/depinject/binding_test.go) while maintaining high level readability. Example 2 [depinject table driven tests](https://github.com/cosmos/cosmos-sdk/blob/main/depinject/provider_desc_test.go) @@ -103,7 +103,7 @@ exercises [HandleEquivocationEvidence](https://github.com/cosmos/cosmos-sdk/blob keeper. Example 3 - Integration suite app configurations may also be specified via golang (not -YAML as above) [statically](https://github.com/cosmos/cosmos-sdk/blob/main/x/nft/testutil/app_config.go) or [dynamically](https://github.com/cosmos/cosmos-sdk/blob/8c23f6f957d1c0bedd314806d1ac65bea59b084c/tests/integration/bank/keeper/keeper_test.go#L129-L134). +YAML as above) statically or [dynamically](https://github.com/cosmos/cosmos-sdk/blob/8c23f6f957d1c0bedd314806d1ac65bea59b084c/tests/integration/bank/keeper/keeper_test.go#L129-L134). #### Limitations @@ -141,9 +141,9 @@ managing their life cycle. #### Limitations -* [A success](https://github.com/cosmos/cosmos-sdk/runs/7606931983?check_suite_focus=true) may take a long time to run, 7-10 minutes per simulation in CI. -* [Timeouts](https://github.com/cosmos/cosmos-sdk/runs/7606932295?check_suite_focus=true) sometimes occur on apparent successes without any indication why. -* Useful error messages not provided on [failure](https://github.com/cosmos/cosmos-sdk/runs/7606932548?check_suite_focus=true) from CI, requiring a developer to run +* A success may take a long time to run, 7-10 minutes per simulation in CI. +* Timeouts sometimes occur on apparent successes without any indication why. +* Useful error messages not provided on failure from CI, requiring a developer to run the simulation locally to reproduce. ### E2E tests diff --git a/sdk/v0.50/build/architecture/adr-076-tx-malleability.mdx b/sdk/v0.50/build/architecture/adr-076-tx-malleability.mdx index 02ab032a..1294d47c 100644 --- a/sdk/v0.50/build/architecture/adr-076-tx-malleability.mdx +++ b/sdk/v0.50/build/architecture/adr-076-tx-malleability.mdx @@ -90,7 +90,7 @@ representation. #### Fields not covered by Amino JSON -Another area that needs to be addressed carefully is the discrepancy between `AminoSignDoc`(see [`aminojson.proto`](https://github.com/cosmos/cosmos-sdk/blob/v0.50/x/tx/signing/aminojson/internal/aminojsonpb/aminojson.proto)) used for `SIGN_MODE_LEGACY_AMINO_JSON` and the actual contents of `TxBody` and `AuthInfo` (see [`tx.proto`](https://github.com/cosmos/cosmos-sdk/blob/v0.50/proto/cosmos/tx/v1beta1/tx.proto)). +Another area that needs to be addressed carefully is the discrepancy between `AminoSignDoc`(see [`aminojson.proto`](https://github.com/cosmos/cosmos-sdk/blob/v0.50.10/x/tx/signing/aminojson/internal/aminojsonpb/aminojson.proto)) used for `SIGN_MODE_LEGACY_AMINO_JSON` and the actual contents of `TxBody` and `AuthInfo` (see [`tx.proto`](https://github.com/cosmos/cosmos-sdk/blob/v0.50.10/proto/cosmos/tx/v1beta1/tx.proto)). If fields get added to `TxBody` or `AuthInfo`, they must either have a corresponding representing in `AminoSignDoc` or Amino JSON signatures must be rejected when those new fields are set. Making sure that this is done is a highly manual process, and developers could easily make the mistake of updating `TxBody` or `AuthInfo` without paying any attention to the implementation of `GetSignBytes` for Amino JSON. This is a critical @@ -169,5 +169,5 @@ or get rejected. * [ADR 027: Deterministic Protobuf Serialization](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-027-deterministic-protobuf-serialization.md) * [ADR 020](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-020-protobuf-transaction-encoding.md#unknown-field-filtering) -* [`aminojson.proto`](https://github.com/cosmos/cosmos-sdk/blob/v0.50/x/tx/signing/aminojson/internal/aminojsonpb/aminojson.proto) -* [`tx.proto`](https://github.com/cosmos/cosmos-sdk/blob/v0.50/proto/cosmos/tx/v1beta1/tx.proto) +* [`aminojson.proto`](https://github.com/cosmos/cosmos-sdk/blob/v0.50.10/x/tx/signing/aminojson/internal/aminojsonpb/aminojson.proto) +* [`tx.proto`](https://github.com/cosmos/cosmos-sdk/blob/v0.50.10/proto/cosmos/tx/v1beta1/tx.proto) diff --git a/sdk/v0.50/build/building-modules/simulator.mdx b/sdk/v0.50/build/building-modules/simulator.mdx index 11ffd83c..4309759d 100644 --- a/sdk/v0.50/build/building-modules/simulator.mdx +++ b/sdk/v0.50/build/building-modules/simulator.mdx @@ -35,7 +35,7 @@ for the key-value pairs from the stores to be decoded (*i.e* unmarshalled) to their corresponding types. In particular, it matches the key to a concrete type and then unmarshals the value from the `KVPair` to the type provided. -You can use the example [here](https://github.com/cosmos/cosmos-sdk/blob/v/x/distribution/simulation/decoder.go) from the distribution module to implement your store decoders. +You can use the example [here](https://github.com/cosmos/cosmos-sdk/blob/v0.50/x/distribution/simulation/decoder.go) from the distribution module to implement your store decoders. ### Randomized genesis @@ -46,13 +46,13 @@ Once the module genesis parameter are generated randomly (or with the key and values defined in a `params` file), they are marshaled to JSON format and added to the app genesis JSON to use it on the simulations. -You can check an example on how to create the randomized genesis [here](https://github.com/cosmos/cosmos-sdk/blob/v/x/staking/simulation/genesis.go). +You can check an example on how to create the randomized genesis [here](https://github.com/cosmos/cosmos-sdk/blob/v0.50/x/staking/simulation/genesis.go). ### Randomized parameter changes The simulator is able to test parameter changes at random. The simulator package from each module must contain a `RandomizedParams` func that will simulate parameter changes of the module throughout the simulations lifespan. -You can see how an example of what is needed to fully test parameter changes [here](https://github.com/cosmos/cosmos-sdk/blob/v/x/staking/simulation/params.go) +You can see how an example of what is needed to fully test parameter changes [here](https://github.com/cosmos/cosmos-sdk/blob/v0.50/x/staking/simulation/params.go) ### Random weighted operations diff --git a/sdk/v0.50/build/migrations/upgrade-reference.mdx b/sdk/v0.50/build/migrations/upgrade-reference.mdx index a036a6d3..c5f899d8 100644 --- a/sdk/v0.50/build/migrations/upgrade-reference.mdx +++ b/sdk/v0.50/build/migrations/upgrade-reference.mdx @@ -28,7 +28,7 @@ Clients that use this feature may now submit their transactions in a fire-and-fo To submit an unordered transaction, clients must set the `unordered` flag to `true` and ensure a reasonable `timeout_timestamp` is set. The `timeout_timestamp` is used as a TTL for the transaction and provides replay protection. Each transaction's `timeout_timestamp` must be -unique to the account; however, the difference may be as small as a nanosecond. See [ADR-070](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-070-unordered-transactions.md) for more details. +unique to the account; however, the difference may be as small as a nanosecond. See [ADR-070](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-070-unordered-account.md) for more details. Note that unordered transactions require sequence values to be zero, and will **FAIL** if a non-zero sequence value is set. Please ensure no sequence value is set when submitting an unordered transaction. diff --git a/sdk/v0.50/build/tooling/cosmovisor.mdx b/sdk/v0.50/build/tooling/cosmovisor.mdx index fcec2eb3..7d80a79b 100644 --- a/sdk/v0.50/build/tooling/cosmovisor.mdx +++ b/sdk/v0.50/build/tooling/cosmovisor.mdx @@ -330,7 +330,7 @@ cosmovisor run start Update app to the latest version (e.g. v0.45). -Next, we can add a migration - which is defined using `x/upgrade` [upgrade plan](https://github.com/cosmos/cosmos-sdk/blob/main/docs/core/upgrade.md) (you may refer to a past version if you are using an older Cosmos SDK release). In a migration we can do any deterministic state change. +Next, we can add a migration - which is defined using `x/upgrade` [upgrade plan](https://github.com/cosmos/cosmos-sdk/blob/main/docs/docs/build/building-apps/03-app-upgrade.md) (you may refer to a past version if you are using an older Cosmos SDK release). In a migration we can do any deterministic state change. Build the new version `simd` binary: diff --git a/sdk/v0.50/build/tooling/hubl.mdx b/sdk/v0.50/build/tooling/hubl.mdx index f7b193ca..70bc5529 100644 --- a/sdk/v0.50/build/tooling/hubl.mdx +++ b/sdk/v0.50/build/tooling/hubl.mdx @@ -3,7 +3,7 @@ title: Hubl --- `Hubl` is a tool that allows you to query any Cosmos SDK based blockchain. -It takes advantage of the new [AutoCLI](https://pkg.go.dev/github.com/cosmos/cosmos-sdk/client/v2@v2.0.0-20220916140313-c5245716b516/cli) feature {/* TODO replace with AutoCLI docs */} of the Cosmos SDK. +It takes advantage of the new [AutoCLI](https://pkg.go.dev/github.com/cosmos/cosmos-sdk/client/v2) feature {/* TODO replace with AutoCLI docs */} of the Cosmos SDK. ## Installation diff --git a/sdk/v0.50/learn/intro/overview.mdx b/sdk/v0.50/learn/intro/overview.mdx index 32fd4a2e..c4ba8c58 100644 --- a/sdk/v0.50/learn/intro/overview.mdx +++ b/sdk/v0.50/learn/intro/overview.mdx @@ -38,4 +38,4 @@ The Cosmos SDK is the most advanced framework for building custom modular applic ## Getting started with the Cosmos SDK * Learn more about the [architecture of a Cosmos SDK application](/sdk/v0.50/learn/intro/sdk-app-architecture) -* Learn how to build an application-specific blockchain from scratch with the [Cosmos SDK Tutorial](https://cosmos.network/docs/tutorial) +* Learn how to build an application-specific blockchain from scratch with the [Cosmos SDK Tutorial](https://tutorials.cosmos.network) diff --git a/sdk/v0.50/user/run-node/keyring.mdx b/sdk/v0.50/user/run-node/keyring.mdx index 915f8a56..2ba463a9 100644 --- a/sdk/v0.50/user/run-node/keyring.mdx +++ b/sdk/v0.50/user/run-node/keyring.mdx @@ -27,7 +27,7 @@ is a list of the most popular operating systems and their respective passwords m * Windows: [Credentials Management API](https://docs.microsoft.com/en-us/windows/win32/secauthn/credentials-management) * GNU/Linux: * [libsecret](https://gitlab.gnome.org/GNOME/libsecret) - * [kwallet](https://api.kde.org/frameworks/kwallet/html/index.html) + * [kwallet](https://api.kde.org/kwallet-index.html) * [keyctl](https://www.kernel.org/doc/html/latest/security/keys/core.html) GNU/Linux distributions that use GNOME as default desktop environment typically come with @@ -91,7 +91,7 @@ one you may want to use specifically to encrypt the password store. The `kwallet` backend uses `KDE Wallet Manager`, which comes installed by default on the GNU/Linux distributions that ships KDE as default desktop environment. Please refer to -[KWallet Handbook](https://docs.kde.org/stable5/en/kdeutils/kwallet5/index.html) for more +[KWallet Handbook](https://userbase.kde.org/KDE_Wallet_Manager) for more information. ### The `keyctl` backend diff --git a/sdk/v0.50/user/run-node/run-production.mdx b/sdk/v0.50/user/run-node/run-production.mdx index 02e66b69..bdb7bc3f 100644 --- a/sdk/v0.50/user/run-node/run-production.mdx +++ b/sdk/v0.50/user/run-node/run-production.mdx @@ -10,7 +10,7 @@ This section describes how to securely run a node in a public setting and/or on When operating a node, full node or validator, in production it is important to set your server up securely. -There are many different ways to secure a server and your node, the described steps here is one way. To see another way of setting up a server see the [run in production tutorial](https://tutorials.cosmos.network/hands-on-exercise/5-run-in-prod/1-overview.html). +There are many different ways to secure a server and your node, the described steps here is one way. To see another way of setting up a server see the [run in production tutorial](https://tutorials.cosmos.network/hands-on-exercise/4-run-in-prod). diff --git a/sdk/v0.53/build/architecture/adr-016-validator-consensus-key-rotation.mdx b/sdk/v0.53/build/architecture/adr-016-validator-consensus-key-rotation.mdx index f8e5161f..c69d3ef2 100644 --- a/sdk/v0.53/build/architecture/adr-016-validator-consensus-key-rotation.mdx +++ b/sdk/v0.53/build/architecture/adr-016-validator-consensus-key-rotation.mdx @@ -116,7 +116,7 @@ Proposed ### Positive * Validators can immediately or periodically rotate their consensus key to have better security policy -* improved security against Long-Range attacks ([Link](https://nearprotocol.com/blog/long-range-attacks-and-a-new-fork-choice-rule)) given a validator throws away the old consensus key(s) +* improved security against Long-Range attacks given a validator throws away the old consensus key(s) ### Negative diff --git a/sdk/v0.53/build/architecture/adr-033-protobuf-inter-module-comm.mdx b/sdk/v0.53/build/architecture/adr-033-protobuf-inter-module-comm.mdx index 140803f2..a14e343e 100644 --- a/sdk/v0.53/build/architecture/adr-033-protobuf-inter-module-comm.mdx +++ b/sdk/v0.53/build/architecture/adr-033-protobuf-inter-module-comm.mdx @@ -23,7 +23,7 @@ service definitions defined in [ADR 021](/sdk/v0.50/build/architecture/adr-021-p ## Context -In the current Cosmos SDK documentation on the [Object-Capability Model](/sdk/v0.50/learn/advanced/ocap), it is stated that: +In the current Cosmos SDK documentation on the [Object-Capability Model](/sdk/v0.53/learn/advanced/ocap), it is stated that: > We assume that a thriving ecosystem of Cosmos SDK modules that are easy to compose into a blockchain application will contain faulty or malicious modules. @@ -452,4 +452,4 @@ replacing `Keeper` interfaces altogether. * [ADR 031](/sdk/v0.50/build/architecture/adr-031-msg-service) * [ADR 028](/sdk/v0.50/build/architecture/adr-028-public-key-addresses) * [ADR 030 draft](https://github.com/cosmos/cosmos-sdk/pull/7105) -* [Object-Capability Model](https://docs.network.com/main/core/ocap) +* [Object-Capability Model](/sdk/v0.53/learn/advanced/ocap) diff --git a/sdk/v0.53/build/architecture/adr-040-storage-and-smt-state-commitments.mdx b/sdk/v0.53/build/architecture/adr-040-storage-and-smt-state-commitments.mdx index cce1c598..bd628eef 100644 --- a/sdk/v0.53/build/architecture/adr-040-storage-and-smt-state-commitments.mdx +++ b/sdk/v0.53/build/architecture/adr-040-storage-and-smt-state-commitments.mdx @@ -293,5 +293,5 @@ We were discussing use case where modules can use a support database, which is n * Facebook Diem (Libra) SMT [design](https://developers.diem.com/papers/jellyfish-merkle-tree/2021-01-14.pdf) * [Trillian Revocation Transparency](https://github.com/google/trillian/blob/master/docs/papers/RevocationTransparency.pdf), [Trillian Verifiable Data Structures](https://github.com/google/trillian/blob/master/docs/papers/VerifiableDataStructures.pdf). * Design and implementation [discussion](https://github.com/cosmos/cosmos-sdk/discussions/8297). -* [How to Upgrade IBC Chains and their Clients](https://github.com/cosmos/ibc-go/blob/main/ibc/upgrades/quick-guide.md) +* [How to Upgrade IBC Chains and their Clients](https://github.com/cosmos/ibc-go/blob/main/docs/docs/01-ibc/05-upgrades/01-quick-guide.md) * [ADR-40 Effect on IBC](https://github.com/cosmos/ibc-go/discussions/256) diff --git a/sdk/v0.53/build/architecture/adr-049-state-sync-hooks.mdx b/sdk/v0.53/build/architecture/adr-049-state-sync-hooks.mdx index 6b7fd5a9..87986cd4 100644 --- a/sdk/v0.53/build/architecture/adr-049-state-sync-hooks.mdx +++ b/sdk/v0.53/build/architecture/adr-049-state-sync-hooks.mdx @@ -194,4 +194,4 @@ Test cases for an implementation are mandatory for ADRs that are affecting conse * [Link](https://github.com/cosmos/cosmos-sdk/pull/10961) * [Link](https://github.com/cosmos/cosmos-sdk/issues/7340) -* [Link](https://hackmd.io/gJoyev6DSmqqkO667WQlGw) + diff --git a/sdk/v0.53/build/architecture/adr-054-semver-compatible-modules.mdx b/sdk/v0.53/build/architecture/adr-054-semver-compatible-modules.mdx index bc9d9f18..516d8827 100644 --- a/sdk/v0.53/build/architecture/adr-054-semver-compatible-modules.mdx +++ b/sdk/v0.53/build/architecture/adr-054-semver-compatible-modules.mdx @@ -476,7 +476,7 @@ languages, possibly executed within a WASM VM. ### Minor API Revisions To declare minor API revisions of proto files, we propose the following guidelines (which were already documented -in [cosmos.app.v1alpha module options](https://github.com/cosmos/cosmos-sdk/blob/v0.50/proto/cosmos/app/v1alpha1/module.proto)): +in [cosmos.app.v1alpha module options](https://github.com/cosmos/cosmos-sdk/blob/v0.50.10/proto/cosmos/app/v1alpha1/module.proto)): * proto packages which are revised from their initial version (considered revision `0`) should include a `package` * comment in some .proto file containing the test `Revision N` at the start of a comment line where `N` is the current diff --git a/sdk/v0.53/build/architecture/adr-059-test-scopes.mdx b/sdk/v0.53/build/architecture/adr-059-test-scopes.mdx index 903c8c2a..0b68197e 100644 --- a/sdk/v0.53/build/architecture/adr-059-test-scopes.mdx +++ b/sdk/v0.53/build/architecture/adr-059-test-scopes.mdx @@ -61,7 +61,7 @@ Tests which exercise a whole module's function with dependencies mocked, are *jo These are almost like integration tests in that they exercise many things together but still use mocks. -Example 1 journey vs illustrative tests - [depinject's BDD style tests](https://github.com/cosmos/cosmos-sdk/blob/main/depinject/features/bindings.feature), show how we can +Example 1 journey vs illustrative tests - depinject's BDD style tests, show how we can rapidly build up many illustrative cases demonstrating behavioral rules without [very much code](https://github.com/cosmos/cosmos-sdk/blob/main/depinject/binding_test.go) while maintaining high level readability. Example 2 [depinject table driven tests](https://github.com/cosmos/cosmos-sdk/blob/main/depinject/provider_desc_test.go) @@ -103,7 +103,7 @@ exercises [HandleEquivocationEvidence](https://github.com/cosmos/cosmos-sdk/blob keeper. Example 3 - Integration suite app configurations may also be specified via golang (not -YAML as above) [statically](https://github.com/cosmos/cosmos-sdk/blob/main/x/nft/testutil/app_config.go) or [dynamically](https://github.com/cosmos/cosmos-sdk/blob/8c23f6f957d1c0bedd314806d1ac65bea59b084c/tests/integration/bank/keeper/keeper_test.go#L129-L134). +YAML as above) statically or [dynamically](https://github.com/cosmos/cosmos-sdk/blob/8c23f6f957d1c0bedd314806d1ac65bea59b084c/tests/integration/bank/keeper/keeper_test.go#L129-L134). #### Limitations @@ -141,9 +141,9 @@ managing their life cycle. #### Limitations -* [A success](https://github.com/cosmos/cosmos-sdk/runs/7606931983?check_suite_focus=true) may take a long time to run, 7-10 minutes per simulation in CI. -* [Timeouts](https://github.com/cosmos/cosmos-sdk/runs/7606932295?check_suite_focus=true) sometimes occur on apparent successes without any indication why. -* Useful error messages not provided on [failure](https://github.com/cosmos/cosmos-sdk/runs/7606932548?check_suite_focus=true) from CI, requiring a developer to run +* A success may take a long time to run, 7-10 minutes per simulation in CI. +* Timeouts sometimes occur on apparent successes without any indication why. +* Useful error messages not provided on failure from CI, requiring a developer to run the simulation locally to reproduce. ### E2E tests diff --git a/sdk/v0.53/build/architecture/adr-076-tx-malleability.mdx b/sdk/v0.53/build/architecture/adr-076-tx-malleability.mdx index 02ab032a..1294d47c 100644 --- a/sdk/v0.53/build/architecture/adr-076-tx-malleability.mdx +++ b/sdk/v0.53/build/architecture/adr-076-tx-malleability.mdx @@ -90,7 +90,7 @@ representation. #### Fields not covered by Amino JSON -Another area that needs to be addressed carefully is the discrepancy between `AminoSignDoc`(see [`aminojson.proto`](https://github.com/cosmos/cosmos-sdk/blob/v0.50/x/tx/signing/aminojson/internal/aminojsonpb/aminojson.proto)) used for `SIGN_MODE_LEGACY_AMINO_JSON` and the actual contents of `TxBody` and `AuthInfo` (see [`tx.proto`](https://github.com/cosmos/cosmos-sdk/blob/v0.50/proto/cosmos/tx/v1beta1/tx.proto)). +Another area that needs to be addressed carefully is the discrepancy between `AminoSignDoc`(see [`aminojson.proto`](https://github.com/cosmos/cosmos-sdk/blob/v0.50.10/x/tx/signing/aminojson/internal/aminojsonpb/aminojson.proto)) used for `SIGN_MODE_LEGACY_AMINO_JSON` and the actual contents of `TxBody` and `AuthInfo` (see [`tx.proto`](https://github.com/cosmos/cosmos-sdk/blob/v0.50.10/proto/cosmos/tx/v1beta1/tx.proto)). If fields get added to `TxBody` or `AuthInfo`, they must either have a corresponding representing in `AminoSignDoc` or Amino JSON signatures must be rejected when those new fields are set. Making sure that this is done is a highly manual process, and developers could easily make the mistake of updating `TxBody` or `AuthInfo` without paying any attention to the implementation of `GetSignBytes` for Amino JSON. This is a critical @@ -169,5 +169,5 @@ or get rejected. * [ADR 027: Deterministic Protobuf Serialization](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-027-deterministic-protobuf-serialization.md) * [ADR 020](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-020-protobuf-transaction-encoding.md#unknown-field-filtering) -* [`aminojson.proto`](https://github.com/cosmos/cosmos-sdk/blob/v0.50/x/tx/signing/aminojson/internal/aminojsonpb/aminojson.proto) -* [`tx.proto`](https://github.com/cosmos/cosmos-sdk/blob/v0.50/proto/cosmos/tx/v1beta1/tx.proto) +* [`aminojson.proto`](https://github.com/cosmos/cosmos-sdk/blob/v0.50.10/x/tx/signing/aminojson/internal/aminojsonpb/aminojson.proto) +* [`tx.proto`](https://github.com/cosmos/cosmos-sdk/blob/v0.50.10/proto/cosmos/tx/v1beta1/tx.proto) diff --git a/sdk/v0.53/build/migrations/upgrade-reference.mdx b/sdk/v0.53/build/migrations/upgrade-reference.mdx index 728a1547..7811a2d4 100644 --- a/sdk/v0.53/build/migrations/upgrade-reference.mdx +++ b/sdk/v0.53/build/migrations/upgrade-reference.mdx @@ -28,7 +28,7 @@ Clients that use this feature may now submit their transactions in a fire-and-fo To submit an unordered transaction, clients must set the `unordered` flag to `true` and ensure a reasonable `timeout_timestamp` is set. The `timeout_timestamp` is used as a TTL for the transaction and provides replay protection. Each transaction's `timeout_timestamp` must be -unique to the account; however, the difference may be as small as a nanosecond. See [ADR-070](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-070-unordered-transactions.md) for more details. +unique to the account; however, the difference may be as small as a nanosecond. See [ADR-070](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-070-unordered-account.md) for more details. Note that unordered transactions require sequence values to be zero, and will **FAIL** if a non-zero sequence value is set. Please ensure no sequence value is set when submitting an unordered transaction. diff --git a/sdk/v0.53/user/run-node/keyring.mdx b/sdk/v0.53/user/run-node/keyring.mdx index 6c0a02c4..5e4fe7a6 100644 --- a/sdk/v0.53/user/run-node/keyring.mdx +++ b/sdk/v0.53/user/run-node/keyring.mdx @@ -55,7 +55,7 @@ is a list of the most popular operating systems and their respective password ma * Windows: [Credentials Management API](https://docs.microsoft.com/en-us/windows/win32/secauthn/credentials-management) * GNU/Linux: * [libsecret](https://gitlab.gnome.org/GNOME/libsecret) - * [kwallet](https://api.kde.org/frameworks/kwallet/html/index.html) + * [kwallet](https://api.kde.org/kwallet-index.html) * [keyctl](https://www.kernel.org/doc/html/latest/security/keys/core.html) GNU/Linux distributions that use GNOME as the default desktop environment typically come with @@ -119,7 +119,7 @@ one you may want to use specifically to encrypt the password store. The `kwallet` backend uses `KDE Wallet Manager`, which comes installed by default on the GNU/Linux distributions that ships KDE as default desktop environment. Please refer to -[KWallet Handbook](https://docs.kde.org/stable5/en/kdeutils/kwallet5/index.html) for more +[KWallet Handbook](https://userbase.kde.org/KDE_Wallet_Manager) for more information. ### The `keyctl` backend From a2494d495c0cc93b896b2701fa42eaff2983d435 Mon Sep 17 00:00:00 2001 From: Evan <87997759+evanorti@users.noreply.github.com> Date: Mon, 23 Feb 2026 12:00:34 -0500 Subject: [PATCH 03/13] Update getting-started.mdx --- sdk/v0.50/tutorials/vote-extensions/oracle/getting-started.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sdk/v0.50/tutorials/vote-extensions/oracle/getting-started.mdx b/sdk/v0.50/tutorials/vote-extensions/oracle/getting-started.mdx index 95e4f3ad..4460736c 100644 --- a/sdk/v0.50/tutorials/vote-extensions/oracle/getting-started.mdx +++ b/sdk/v0.50/tutorials/vote-extensions/oracle/getting-started.mdx @@ -14,7 +14,7 @@ description: What is an Oracle? Implementing Vote Extensions Testing the Oracle Before you start with this tutorial, make sure you have: * A working chain project. This tutorial won't cover the steps of creating a new chain/module. -* Familiarity with the Cosmos SDK. If you're not, we suggest you start with [Cosmos SDK Tutorials](https://tutorials.cosmos.network), as ABCI++ is considered an advanced topic. +* Familiarity with the Cosmos SDK, as ABCI++ is considered an advanced topic. * Read and understood [What is an Oracle?](/sdk/v0.50/tutorials/vote-extensions/oracle/what-is-an-oracle). This provides necessary background information for understanding the Oracle module. * Basic understanding of Go programming language. From 76fc375baf02cf901c72441959a3d9fe3d02f743 Mon Sep 17 00:00:00 2001 From: Evan <87997759+evanorti@users.noreply.github.com> Date: Wed, 25 Feb 2026 15:16:28 -0500 Subject: [PATCH 04/13] update pages --- ibc/next/intro.mdx | 6 +- .../example-usage.mdx | 87 +++++++--- .../packet-forward-middleware/integration.mdx | 146 +++++++---------- .../packet-forward-middleware/overview.mdx | 21 ++- .../rate-limit-middleware/integration.mdx | 148 +++++++++++++++++- .../rate-limit-middleware/overview.mdx | 16 +- .../rate-limit-middleware/setting-limits.mdx | 18 +-- 7 files changed, 297 insertions(+), 145 deletions(-) diff --git a/ibc/next/intro.mdx b/ibc/next/intro.mdx index 36e305c1..09f87a9c 100644 --- a/ibc/next/intro.mdx +++ b/ibc/next/intro.mdx @@ -13,20 +13,20 @@ The protocol realizes this interoperability by specifying a set of data structur **Notice** -Since ibc-go v10, there are two versions of the protocol in the same release: IBC classic and IBC v2. The protocols are seperate - a connection uses either IBC classic or IBC v2 +Since ibc-go v10, there are two versions of the protocol in the same release: IBC classic and IBC v2. The protocols are separate - a connection uses either IBC classic or IBC v2 ## High-level overview of IBC v2 For a high level overview of IBC v2, please refer to [this blog post.](https://ibcprotocol.dev/blog/ibc-v2-announcement) For a more detailed understanding of the IBC v2 protocol, please refer to the [IBC v2 protocol specification.](https://github.com/cosmos/ibc/tree/main/spec/IBC_V2) -If you are interested in using the cannonical deployment of IBC v2, connecting Cosmos chains and Ethereum, take a look at the [IBC Eureka](/skip-go/eureka/eureka-overview) documentation to get started. +If you are interested in using the canonical deployment of IBC v2, connecting Cosmos chains and Ethereum, take a look at the [IBC Eureka](/skip-go/eureka/eureka-overview) documentation to get started. ## High-level overview of IBC Classic The following diagram shows how IBC works at a high level: -![Light Mode IBC Overview](/ibc/images/images/ibcoverview-light.svg#gh-light-mode-only)![Dark Mode IBC Overview](/ibc/images/images/ibcoverview-dark.svg#gh-dark-mode-only) +![Dark Mode IBC Overview](/ibc/images/images/ibcoverview-dark.svg) The transport layer (TAO) provides the necessary infrastructure to establish secure connections and authenticate data packets between chains. The application layer builds on top of the transport layer and defines exactly how data packets should be packaged and interpreted by the sending and receiving chains. diff --git a/ibc/next/middleware/packet-forward-middleware/example-usage.mdx b/ibc/next/middleware/packet-forward-middleware/example-usage.mdx index e689e1e7..a55752e8 100644 --- a/ibc/next/middleware/packet-forward-middleware/example-usage.mdx +++ b/ibc/next/middleware/packet-forward-middleware/example-usage.mdx @@ -61,18 +61,50 @@ sequenceDiagram Chain B ->> Chain A: ACK error ``` +### Multi-hop Transfer A → B → C → D (full success) + +```mermaid +sequenceDiagram + autonumber + Chain A ->> Chain B: PFM transfer + Chain B --> Chain B: recv_packet + Chain B ->> Chain C: forward + Chain C --> Chain C: recv_packet + Chain C ->> Chain D: forward + Chain D --> Chain D: recv_packet + Chain D ->> Chain C: ack + Chain C ->> Chain B: ack + Chain B ->> Chain A: ack +``` + +### Multi-hop Transfer A → B → C → D (error at D, refund to A) + +```mermaid +sequenceDiagram + autonumber + Chain A ->> Chain B: PFM transfer + Chain B --> Chain B: recv_packet + Chain B ->> Chain C: forward + Chain C --> Chain C: recv_packet + Chain C ->> Chain D: forward + Chain D --> Chain D: recv_packet (error) + Chain D ->> Chain C: ACK error + Chain C ->> Chain B: ACK error + Chain B ->> Chain A: ACK error +``` + ### A -> B -> C full success 1. `A` This sends packet over underlying ICS-004 wrapper with memo as is. -2. `B` This receives packet and parses it into ICS-020 packet. -3. `B` Validates `forward` packet on this step, return `ACK` error if fails. -4. `B` If other middleware not yet called ICS-020, call it and ACK error on fail. Tokens minted or unescrowed here. -5. `B` Handle denom. If denom prefix is from `B`, remove it. If denom prefix is other chain - add `B` prefix. -6. `B` Take fee, create new ICS-004 packet with timeout from forward for next step, and remaining inner `memo`. -7. `B` Send transfer to `C` with parameters obtained from `memo`. Tokens burnt or escrowed here. -8. `B` Store tracking `in flight packet` under next `(channel, port, ICS-20 transfer sequence)`, do not `ACK` packet yet. +2. `B` This receives packet and parses it into ICS-020 packet. {/* cosmos/ibc-go modules/apps/packet-forward-middleware/ibc_middleware.go:143-144 — UnmarshalJSON on packet data to FungibleTokenPacketData */} +3. `B` Validates `forward` packet on this step, return `ACK` error if fails. {/* cosmos/ibc-go modules/apps/packet-forward-middleware/ibc_middleware.go:182-184 — metadata.Validate() called; error ACK returned on failure */} +4. `B` If other middleware not yet called ICS-020, call it and ACK error on fail. Tokens minted or unescrowed here. {/* cosmos/ibc-go modules/apps/packet-forward-middleware/ibc_middleware.go:194 — receiveFunds called before forwarding */} +5. `B` Handle denom. If denom prefix matches the source chain's (counterparty, A's) port/channel, remove it (path-unwind). If not — add `B`'s port/channel as prefix. {/* cosmos/ibc-go modules/apps/packet-forward-middleware/ibc_middleware.go:85-101 — getDenomForThisChain: HasPrefix(counterpartyPort, counterpartyChannel) checks A's port/channel; if denom trace starts with A's hop, unwind by removing it; otherwise prepend B's destination port/channel */} +6. `B` Create new ICS-004 packet with timeout from forward for next step, and remaining inner `memo`. {/* cosmos/ibc-go modules/apps/packet-forward-middleware/keeper/keeper.go:277 — msgTransfer created with timeout from forward metadata */} +7. `B` Send transfer to `C` with parameters obtained from `memo`. Tokens burnt or escrowed here. {/* cosmos/ibc-go modules/apps/packet-forward-middleware/keeper/keeper.go:279 — k.transferKeeper.Transfer(ctx, msgTransfer) sends the outbound packet */} +8. `B` Store tracking `in flight packet` under next `(channel, port, ICS-20 transfer sequence)`, do not `ACK` packet yet. {/* cosmos/ibc-go modules/apps/packet-forward-middleware/keeper/keeper.go:318 — SetInflightPacket keyed by (channel, port, sequence); ibc_middleware.go:230-232 — nil ack returned to prevent WriteAcknowledgement */} 9. `C` Handle ICS-020 packet as usual. -10. `B` On ICS-020 ACK from `C` find `in flight packet`, delete it and write `ACK` for original packet from `A`. +10. `B` On ICS-020 ACK from `C` find `in flight packet`, delete it and write `ACK` for original packet from `A`. {/* cosmos/ibc-go modules/apps/packet-forward-middleware/ibc_middleware.go:293-301 — GetInflightPacket, RemoveInFlightPacket, WriteAcknowledgementForForwardedPacket */} 11. `A` Handle ICS-020 `ACK` as usual [Example](https://mintscan.io/osmosis-testnet/txs/FAB912347B8729FFCA92AC35E6B1E83BC8169DE7CC2C254A5A3F70C8EC35D771?height=3788973) of USDC transfer from Osmosis -> Noble -> Sei @@ -110,29 +142,44 @@ In the case of a timeout after 10 minutes for either forward, the packet would b `next` as JSON -```json expandable +```json { "forward": { - "receiver": "pfm", / intentionally invalid + "receiver": "pfm", "port": "transfer", - "channel": "channel-123", - "timeout": "10m", - "retries": 2, + "channel": "channel-123", + "timeout": "10m", + "retries": 2, "next": { - "forward": { - "receiver": "chain-d-bech32-address", - "port": "transfer", - "channel": "channel-234", - "timeout": "10m", - "retries": 2 + "forward": { + "receiver": "chain-d-bech32-address", + "port": "transfer", + "channel": "channel-234", + "timeout": "10m", + "retries": 2 } } } } ``` +`next` as escaped JSON string {/* cosmos/ibc-go modules/apps/packet-forward-middleware/types/forward.go:180-185 — getForwardMetadataFromNext: if next is not a map, it is type-asserted as a string and json.Unmarshal is called, so both forms are accepted */} + +```json +{ + "forward": { + "receiver": "pfm", + "port": "transfer", + "channel": "channel-123", + "timeout": "10m", + "retries": 2, + "next": "{\"forward\":{\"receiver\":\"chain-d-bech32-address\",\"port\":\"transfer\",\"channel\":\"channel-234\",\"timeout\":\"10m\",\"retries\":2}}" + } +} +``` + ## Intermediate Address Security -Intermediate chains don’t need a valid receiver address. Instead, they derive a secure address from the packet’s sender and channel, preventing users from forwarding tokens to arbitrary accounts. +Intermediate chains don’t need a valid receiver address. Instead, they derive a secure address from the packet’s sender and channel, preventing users from forwarding tokens to arbitrary accounts. {/* cosmos/ibc-go modules/apps/packet-forward-middleware/ibc_middleware.go:119-121 — GetReceiver uses address.Hash(ModuleName, channel+"/"+sender) to derive a deterministic address; ibc_middleware.go:187-188 — receiver is overridden to prevent forwarding to arbitrary accounts */} To avoid accidental transfers to chains without PFM, use an invalid bech32 address (e.g., "pfm") for intermediate receivers. diff --git a/ibc/next/middleware/packet-forward-middleware/integration.mdx b/ibc/next/middleware/packet-forward-middleware/integration.mdx index e8b01d21..4c51e124 100644 --- a/ibc/next/middleware/packet-forward-middleware/integration.mdx +++ b/ibc/next/middleware/packet-forward-middleware/integration.mdx @@ -2,56 +2,53 @@ title: Integration description: >- This document provides instructions on integrating and configuring the Packet - Forward Middleware (PFM) within your existing chain implementation. The - integration steps include the following: + Forward Middleware (PFM) within your existing chain implementation. --- This document provides instructions on integrating and configuring the Packet Forward Middleware (PFM) within your existing chain implementation. The integration steps include the following: -1. [Import the PFM, initialize the PFM Module & Keeper, initialize the store keys and module params, and initialize the Begin/End Block logic and InitGenesis order](#example-integration-of-the-packet-forward-middleware) +1. [Import the PFM, initialize the PFM Module & Keeper, initialize the store keys, and initialize the Begin/End Block logic and InitGenesis order](#example-integration-of-the-packet-forward-middleware) 2. [Configure the IBC application stack including the transfer module](#configuring-the-transfer-application-stack-with-packet-forward-middleware) -3. [Configuration of additional options such as timeout period, number of retries on timeout, refund timeout period, and fee percentage](#configurable-options-in-the-packet-forward-middleware) +3. [Configuration of additional options such as timeout period and number of retries on timeout](#configurable-options-in-the-packet-forward-middleware) Integration of the PFM should take approximately 20 minutes. ## Example integration of the Packet Forward Middleware -```go expandable -/ app.go +```go +// app.go -/ Import the packet forward middleware +// Import the packet forward middleware import ( - - "github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v10/packetforward" - packetforwardkeeper "github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v10/packetforward/keeper" - packetforwardtypes "github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v10/packetforward/types" + packetforward "github.com/cosmos/ibc-go/v10/modules/apps/packet-forward-middleware" + packetforwardkeeper "github.com/cosmos/ibc-go/v10/modules/apps/packet-forward-middleware/keeper" + packetforwardtypes "github.com/cosmos/ibc-go/v10/modules/apps/packet-forward-middleware/types" ) ... -/ Register the AppModule for the packet forward middleware module +// Register the AppModule for the packet forward middleware module ModuleBasics = module.NewBasicManager( ... - packetforward.AppModuleBasic{ -}, + packetforward.AppModuleBasic{}, ... ) ... -/ Add packet forward middleware Keeper +// Add packet forward middleware Keeper type App struct { - ... - PacketForwardKeeper *packetforwardkeeper.Keeper - ... + ... + PFMKeeper *packetforwardkeeper.Keeper + ... } ... -/ Create store keys - keys := sdk.NewKVStoreKeys( +// Create store keys +keys := sdk.NewKVStoreKeys( ... packetforwardtypes.StoreKey, ... @@ -59,75 +56,52 @@ type App struct { ... -/ Initialize the packet forward middleware Keeper -/ It's important to note that the PFM Keeper must be initialized before the Transfer Keeper -app.PacketForwardKeeper = packetforwardkeeper.NewKeeper( - appCodec, - keys[packetforwardtypes.StoreKey], - nil, / will be zero-value here, reference is set later on with SetTransferKeeper. - app.IBCKeeper.ChannelKeeper, - appKeepers.DistrKeeper, - app.BankKeeper, - app.IBCKeeper.ChannelKeeper, - authtypes.NewModuleAddress(govtypes.ModuleName).String(), -) +// Initialize the transfer module Keeper first (PFM Keeper requires it) +app.TransferKeeper = ibctransferkeeper.NewKeeper(...) -/ Initialize the transfer module Keeper -app.TransferKeeper = ibctransferkeeper.NewKeeper( +// Initialize the packet forward middleware Keeper +app.PFMKeeper = packetforwardkeeper.NewKeeper( appCodec, - keys[ibctransfertypes.StoreKey], - app.GetSubspace(ibctransfertypes.ModuleName), - app.PacketForwardKeeper, + app.AccountKeeper.AddressCodec(), + runtime.NewKVStoreService(keys[packetforwardtypes.StoreKey]), + app.TransferKeeper, app.IBCKeeper.ChannelKeeper, - &app.IBCKeeper.PortKeeper, - app.AccountKeeper, app.BankKeeper, - scopedTransferKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), ) -app.PacketForwardKeeper.SetTransferKeeper(app.TransferKeeper) - -/ See the section below for configuring an application stack with the packet forward middleware +// See the section below for configuring an application stack with the packet forward middleware ... -/ Register packet forward middleware AppModule +// Register packet forward middleware AppModule app.moduleManager = module.NewManager( ... - packetforward.NewAppModule(app.PacketForwardKeeper, app.GetSubspace(packetforwardtypes.ModuleName)), + packetforward.NewAppModule(app.PFMKeeper), ) ... -/ Add packet forward middleware to begin blocker logic +// Add packet forward middleware to begin blocker logic app.moduleManager.SetOrderBeginBlockers( ... packetforwardtypes.ModuleName, ... ) -/ Add packet forward middleware to end blocker logic +// Add packet forward middleware to end blocker logic app.moduleManager.SetOrderEndBlockers( ... packetforwardtypes.ModuleName, ... ) -/ Add packet forward middleware to init genesis logic +// Add packet forward middleware to init genesis logic app.moduleManager.SetOrderInitGenesis( ... packetforwardtypes.ModuleName, ... ) - -/ Add packet forward middleware to init params keeper -func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino, key, tkey storetypes.StoreKey) - -paramskeeper.Keeper { - ... - paramsKeeper.Subspace(packetforwardtypes.ModuleName).WithKeyTable(packetforwardtypes.ParamKeyTable()) - ... -} ``` ## Configuring the transfer application stack with Packet Forward Middleware @@ -136,46 +110,38 @@ Here is an example of how to create an application stack using `transfer` and `p The following `transferStack` is configured in `app/app.go` and added to the IBC `Router`. The in-line comments describe the execution flow of packets between the application stack and IBC core. -For more information on configuring an IBC application stack see the ibc-go docs [here](https://github.com/cosmos/ibc-go/blob/e69a833de764fa0f5bdf0338d9452fd6e579a675/docs/docs/04-middleware/01-ics29-fee/02-integration.md#configuring-an-application-stack-with-fee-middleware). +For more information on configuring an IBC application stack see the [middleware development guide](/ibc/next/ibc/middleware/develop). -```go expandable -/ Create Transfer Stack -/ SendPacket, since it is originating from the application to core IBC: -/ transferKeeper.SendPacket -> packetforward.SendPacket -> channel.SendPacket +```go +// Create Transfer Stack +// SendPacket, since it is originating from the application to core IBC: +// transferKeeper.SendPacket -> packetforward.SendPacket -> channel.SendPacket -/ RecvPacket, message that originates from core IBC and goes down to app, the flow is the other way -/ channel.RecvPacket -> packetforward.OnRecvPacket -> transfer.OnRecvPacket +// RecvPacket, message that originates from core IBC and goes down to app, the flow is the other way +// channel.RecvPacket -> packetforward.OnRecvPacket -> transfer.OnRecvPacket -/ transfer stack contains (from top to bottom): -/ - Packet Forward Middleware -/ - Transfer -var transferStack ibcporttypes.IBCModule -transferStack = transfer.NewIBCModule(app.TransferKeeper) +// transfer stack contains (from top to bottom): +// - Packet Forward Middleware +// - Transfer -transferStack = packetforward.NewIBCMiddleware( - transferStack, - app.PacketForwardKeeper, - 0, / retries on timeout - packetforwardkeeper.DefaultForwardTransferPacketTimeoutTimestamp, / forward timeout -) +// create IBC module from bottom to top of stack +transferStack := porttypes.NewIBCStackBuilder(app.IBCKeeper.ChannelKeeper) +transferStack.Base(transfer.NewIBCModule(app.TransferKeeper)). + Next(packetforward.NewIBCMiddleware( + app.PFMKeeper, + 0, // retries on timeout + packetforwardkeeper.DefaultForwardTransferPacketTimeoutTimestamp, // forward timeout + )) -/ Add transfer stack to IBC Router -ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferStack) +// Add transfer stack to IBC Router +ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferStack.Build()) ``` ## Configurable options in the Packet Forward Middleware -The Packet Forward Middleware has several configurable options available when initializing the IBC application stack. +The Packet Forward Middleware has several configurable options available when initializing the IBC application stack. {/* cosmos/ibc-go modules/apps/packet-forward-middleware/ibc_middleware.go:42 — NewIBCMiddleware(k *keeper.Keeper, retriesOnTimeout uint8, forwardTimeout time.Duration) */} You can see these passed in as arguments to `packetforward.NewIBCMiddleware` and they include the number of retries that -will be performed on a forward timeout, the timeout period that will be used for a forward, and the timeout period that -will be used for performing refunds in the case that a forward is taking too long. - -Additionally, there is a fee percentage parameter that can be set in `InitGenesis`, this is an optional parameter that -can be used to take a fee from each forwarded packet which will then be distributed to the community pool. In the -`OnRecvPacket` callback `ForwardTransferPacket` is invoked which will attempt to subtract a fee from the forwarded -packet amount if the fee percentage is non-zero. - -* Retries On Timeout - how many times will a forward be re-attempted in the case of a timeout. -* Timeout Period - how long can a forward be in progress before giving up. -* Refund Timeout - how long can a forward be in progress before issuing a refund back to the original source chain. -* Fee Percentage - % of the forwarded packet amount which will be subtracted and distributed to the community pool. +will be performed on a forward timeout, and the timeout period that will be used for a forward. + +* Retries On Timeout - how many times will a forward be re-attempted in the case of a timeout. {/* cosmos/ibc-go modules/apps/packet-forward-middleware/keeper/keeper.go:332-333 — TimeoutShouldRetry; keeper/keeper.go:345 — if inFlightPacket.RetriesRemaining <= 0 */} +* Timeout Period - how long can a forward be in progress before giving up. {/* cosmos/ibc-go modules/apps/packet-forward-middleware/ibc_middleware.go:213-214 — falls back to im.forwardTimeout when not specified; keeper/keeper.go:36 — DefaultForwardTransferPacketTimeoutTimestamp = 10 minutes */} diff --git a/ibc/next/middleware/packet-forward-middleware/overview.mdx b/ibc/next/middleware/packet-forward-middleware/overview.mdx index 482fc16d..e495e6fd 100644 --- a/ibc/next/middleware/packet-forward-middleware/overview.mdx +++ b/ibc/next/middleware/packet-forward-middleware/overview.mdx @@ -1,34 +1,33 @@ --- title: Overview +description: Packet Forward Middleware enables multi-hop IBC token transfers through intermediate chains. --- -Packet forward middleware is only compatible with IBC classic, not IBC v2 +Packet forward middleware is only compatible with IBC classic, not IBC v2 {/* cosmos/ibc-go modules/apps/packet-forward-middleware/ibc_middleware.go:27-28 — implements porttypes.Middleware and porttypes.PacketUnmarshalerModule only; no api.IBCModule implementation */} Learn about packet forward middleware, a middleware that can be used in combination with token transfers (ICS-20) ## What is Packet Forward Middleware? -Packet Forward Middleware enables multi-hop token transfers by forwarding IBC packets through intermediate chains, which may not be directly connected. It supports: +Packet Forward Middleware enables multi-hop token transfers by forwarding IBC packets through intermediate chains, which may not be directly connected. {/* cosmos/ibc-go modules/apps/packet-forward-middleware/keeper/keeper.go:255 — ForwardTransferPacket is the core function that handles forwarding a packet to the next hop */} It supports: * **Path-Unwinding Functionality:** - Because the fungibility of tokens transferred between chains is determined by [the path the tokens have travelled](/ibc/next/apps/transfer/overview#denomination-trace), i.e. the same token sent from chain A to chain B is not fungible with the same token sent from chain A, to chain C and then to chain B, packet forward middleware also enables routing tokens back through their source, before sending onto the final destination. + Because the fungibility of tokens transferred between chains is determined by [the path the tokens have travelled](/ibc/next/apps/transfer/overview#denomination-trace), i.e. the same token sent from chain A to chain B is not fungible with the same token sent from chain A, to chain C and then to chain B, packet forward middleware also enables routing tokens back through their source, before sending onto the final destination. {/* cosmos/ibc-go modules/apps/packet-forward-middleware/ibc_middleware.go:85-101 — getDenomForThisChain removes the denom prefix if it originates from the current chain, or adds a prefix otherwise */} * **Asynchronous Acknowledgements:** - Acknowledgements are only written to the origin chain after all forwarding steps succeed or fail, users only need to monitor the source chain for the result. + Multi-hop sequences are atomic: acknowledgements are only written to the origin chain after all forwarding steps succeed or fail, so users only need to monitor the source chain for the result. {/* cosmos/ibc-go modules/apps/packet-forward-middleware/ibc_middleware.go:230-232 — nil ack prevents WriteAcknowledgement for forwarded packet; keeper/keeper.go:167-168 — WriteAcknowledgementForForwardedPacket propagates both success and error acks back to the original packet */} * **Retry and Timeout Handling:** - The middleware can be configured to retry forwarding in the case that there was a timeout. + The middleware can be configured to retry forwarding in the case that there was a timeout. {/* cosmos/ibc-go modules/apps/packet-forward-middleware/ibc_middleware.go:37 — retriesOnTimeout uint8 field; keeper/keeper.go:332-333 — TimeoutShouldRetry checks remaining retries */} * **Forwarding across multiple chains with nested memos:** - Instructions on which route to take to forward a packet across more than one chain can be set within a nested JSON with the memo field -* **Configurable Fee Deduction on Recieve:** - Integrators of PFM can choose to deduct a percentage of tokens forwarded through their chain and distribute these tokens to the community pool. + Instructions on which route to take to forward a packet across more than one chain can be set within a nested JSON with the memo field. {/* cosmos/ibc-go modules/apps/packet-forward-middleware/types/forward.go:32 — Next *PacketMetadata enables chaining multiple hops; types/keys.go:23 — ForwardNextKey = "next" */} ## How it works? -1. User initiates a `MsgTransfer` with a memo JSON payload containing forwarding instructions. +1. User initiates a `MsgTransfer` with a memo JSON payload containing forwarding instructions. {/* cosmos/ibc-go modules/apps/packet-forward-middleware/types/keys.go:17 — ForwardMetadataKey = "forward" is the expected top-level JSON key in the memo */} -2. Intermediate chains (with PFM enabled) parse the memo and forward the packet to the destination specified. +2. Intermediate chains (with PFM enabled) parse the memo and forward the packet to the destination specified. {/* cosmos/ibc-go modules/apps/packet-forward-middleware/ibc_middleware.go:166 — GetPacketMetadataFromPacketdata extracts ForwardMetadata from the packet data's memo field */} -3. Acknowledgements are passed back step-by-step to the origin chain after the final hop succeeds or fails, along the same path used for forwarding. +3. Acknowledgements are passed back step-by-step to the origin chain after the final hop succeeds or fails, along the same path used for forwarding. {/* cosmos/ibc-go modules/apps/packet-forward-middleware/ibc_middleware.go:293-301 — OnAcknowledgementPacket retrieves the in-flight packet, removes it, and calls WriteAcknowledgementForForwardedPacket */} In practise, it can be challenging to correctly format the memo for the desired route. It is recommended to use the Skip API to correctly format the memo needed in `MsgTransfer` to make this easy. diff --git a/ibc/next/middleware/rate-limit-middleware/integration.mdx b/ibc/next/middleware/rate-limit-middleware/integration.mdx index c97f41be..ca51a806 100644 --- a/ibc/next/middleware/rate-limit-middleware/integration.mdx +++ b/ibc/next/middleware/rate-limit-middleware/integration.mdx @@ -1,8 +1,148 @@ --- title: Integration -description: >- - This section should be completed once the middleware wiring approach is - finalised. +description: Integrate and configure Rate + Limit Middleware. --- -This section should be completed once the middleware wiring approach is finalised. +This document provides instructions on integrating and configuring the Rate Limit Middleware within your existing chain implementation. + +## Example integration of the Rate Limit Middleware + +```go +// app.go + +// Import the rate limit middleware +import ( + ratelimiting "github.com/cosmos/ibc-go/v10/modules/apps/rate-limiting" + ratelimitkeeper "github.com/cosmos/ibc-go/v10/modules/apps/rate-limiting/keeper" + ratelimittypes "github.com/cosmos/ibc-go/v10/modules/apps/rate-limiting/types" +) + +... + +// Register the AppModule for the rate limiting module +ModuleBasics = module.NewBasicManager( + ... + ratelimiting.AppModuleBasic{}, + ... +) + +... + +// Add rate limiting Keeper +type App struct { + ... + RateLimitKeeper *ratelimitkeeper.Keeper + ... +} + +... + +// Create store keys +keys := sdk.NewKVStoreKeys( + ... + ratelimittypes.StoreKey, + ... +) + +... + +// Initialize the rate limit middleware Keeper +app.RateLimitKeeper = ratelimitkeeper.NewKeeper( + appCodec, + app.AccountKeeper.AddressCodec(), + runtime.NewKVStoreService(keys[ratelimittypes.StoreKey]), + app.IBCKeeper.ChannelKeeper, + app.IBCKeeper.ClientKeeper, + app.BankKeeper, + authtypes.NewModuleAddress(govtypes.ModuleName).String(), +) + +// See the section below for configuring an application stack with the rate limit middleware + +... + +// Register rate limiting AppModule +app.moduleManager = module.NewManager( + ... + ratelimiting.NewAppModule(app.RateLimitKeeper), +) + +... + +// Add rate limiting to begin blocker logic (required for periodic rate limit resets) +app.moduleManager.SetOrderBeginBlockers( + ... + ratelimittypes.ModuleName, + ... +) + +// Add rate limiting to end blocker logic +app.moduleManager.SetOrderEndBlockers( + ... + ratelimittypes.ModuleName, + ... +) + +// Add rate limiting to init genesis logic +app.moduleManager.SetOrderInitGenesis( + ... + ratelimittypes.ModuleName, + ... +) +``` + +## Configuring the transfer application stack with Rate Limit Middleware + +Here is an example of how to create an application stack using `transfer` and `rate-limiting`. +The following `transferStack` is configured in `app/app.go` and added to the IBC `Router`. +The in-line comments describe the execution flow of packets between the application stack and IBC core. + +For more information on configuring an IBC application stack see the [middleware development guide](/ibc/next/ibc/middleware/develop). + +```go +// Create Transfer Stack +// SendPacket, since it is originating from the application to core IBC: +// transferKeeper.SendPacket -> ratelimit.SendPacket -> channel.SendPacket + +// RecvPacket, message that originates from core IBC and goes down to app, the flow is the other way +// channel.RecvPacket -> ratelimit.OnRecvPacket -> transfer.OnRecvPacket + +// transfer stack contains (from top to bottom): +// - Rate Limit Middleware +// - Transfer + +// create IBC module from bottom to top of stack +transferStack := porttypes.NewIBCStackBuilder(app.IBCKeeper.ChannelKeeper) +transferStack.Base(transfer.NewIBCModule(app.TransferKeeper)). + Next(ratelimiting.NewIBCMiddleware(app.RateLimitKeeper)) + +// Add transfer stack to IBC Router +ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferStack.Build()) +``` + +## Using Rate Limit Middleware with Packet Forward Middleware + +If both PFM and Rate Limit Middleware are integrated, they can be stacked together. In the reference implementation, Rate Limit Middleware is placed above PFM so that rate limits are enforced on the final inbound transfer before forwarding: {/* cosmos/ibc-go simapp/app.go:416 — "transfer stack contains (from top to bottom): RateLimit, PacketForward, Transfer"; RecvPacket flow at line 414 confirms RateLimit processes first */} + +```go +// transfer stack contains (from top to bottom): +// - Rate Limit Middleware +// - Packet Forward Middleware +// - Transfer + +// SendPacket flow: transferKeeper.SendPacket -> PFM.SendPacket -> RateLimit.SendPacket -> channel.SendPacket +// RecvPacket flow: channel.RecvPacket -> RateLimit.OnRecvPacket -> PFM.OnRecvPacket -> transfer.OnRecvPacket + +// create IBC module from bottom to top of stack +transferStack := porttypes.NewIBCStackBuilder(app.IBCKeeper.ChannelKeeper) +transferStack.Base(transfer.NewIBCModule(app.TransferKeeper)). + Next(packetforward.NewIBCMiddleware( + app.PFMKeeper, + 0, // retries on timeout + packetforwardkeeper.DefaultForwardTransferPacketTimeoutTimestamp, + )). + Next(ratelimiting.NewIBCMiddleware(app.RateLimitKeeper)) + +ibcRouter.AddRoute(ibctransfertypes.ModuleName, transferStack.Build()) +``` diff --git a/ibc/next/middleware/rate-limit-middleware/overview.mdx b/ibc/next/middleware/rate-limit-middleware/overview.mdx index f88ae6a3..795668ba 100644 --- a/ibc/next/middleware/rate-limit-middleware/overview.mdx +++ b/ibc/next/middleware/rate-limit-middleware/overview.mdx @@ -10,20 +10,20 @@ Learn about rate limit middleware, a middleware that can be used in combination ## What is Rate Limit Middleware? -The rate limit middleware enforces rate limits on IBC token transfers coming into and out of a chain. It supports: +The rate limit middleware enforces rate limits on IBC token transfers coming into and out of a chain. {/* cosmos/ibc-go modules/apps/rate-limiting/ibc_middleware.go:64 — "Rate limits the incoming packet"; outbound enforced via SendRateLimitedPacket at line 97 */} It supports: -* **Risk Mitigation:** In case of a bug exploit, attack or economic failure of a connected chain, it limits the impact to the in/outflow specified for a given time period. -* **Token Filtering:** Through the use of a blacklist, the middleware can completely block tokens entering or leaving a domain, relevant for complicance or giving asset issuers greater control over the domains token can be sent to. -* **Uninterupted Packet Flow:** When desired, rate limits can be bypassed by using the whitelist, to avoid any restriction on asset in or outflows. +* **Risk Mitigation:** In case of a bug exploit, attack or economic failure of a connected chain, it limits the impact to the in/outflow specified {/* cosmos/ibc-go modules/apps/rate-limiting/types/quota.go:7 — CheckExceedsQuota enforces the threshold cap */} for a given time period. {/* cosmos/ibc-go modules/apps/rate-limiting/keeper/abci.go:8 — BeginBlocker resets limits that have expired based on DurationHours */} +* **Token Filtering:** Through the use of a blacklist, the middleware can completely block tokens entering or leaving a domain, {/* cosmos/ibc-go modules/apps/rate-limiting/keeper/blacklist.go:12 — "Adds a denom to a blacklist to prevent all IBC transfers with that denom" */} relevant for compliance or giving asset issuers greater control over the domains token can be sent to. +* **Uninterrupted Packet Flow:** When desired, rate limits can be bypassed by using the whitelist, to avoid any restriction on asset in or outflows. {/* cosmos/ibc-go modules/apps/rate-limiting/keeper/whitelist.go:12 — "allow all IBC transfers between those addresses to skip all flow calculations" */} ## How it works The rate limiting middleware determines whether tokens can flow into or out of a chain. The middleware does this by: -1. Check transfer limits for an asset (Quota): When tokens are recieved or sent, the middleware determines whether the amount of tokens flowing in or out have exceeded the limit. +1. Check transfer limits for an asset (Quota): When tokens are received or sent, the middleware determines whether the amount of tokens flowing in or out have exceeded the limit. {/* cosmos/ibc-go modules/apps/rate-limiting/keeper/flow.go:18 — CheckRateLimitAndUpdateFlow "checks whether the given packet will exceed the rate limit" */} -2. Track in or outflow: When tokens enter or leave the chain, the amount transferred is tracked in state +2. Track in or outflow: When tokens enter or leave the chain, the amount transferred is tracked in state. {/* cosmos/ibc-go modules/apps/rate-limiting/keeper/flow.go:52 — SetRateLimit persists the updated Inflow/Outflow counters after each packet */} -3. Block or allow token flow: Dependent on the limit, the middleware will either allow the tokens to pass through or block the tokens. +3. Block or allow token flow: Dependent on the limit, the middleware will either allow the tokens to pass through or block the tokens. {/* cosmos/ibc-go modules/apps/rate-limiting/ibc_middleware.go:66 — ReceiveRateLimitedPacket error returns error ack (blocked); success passes to underlying app at line 72 */} -4. Handle failures: If the packet timesout or fails to be delivered, the middleware ensures limits are correctly recorded. +4. Handle failures: If the packet timesout or fails to be delivered, the middleware ensures limits are correctly recorded. {/* cosmos/ibc-go modules/apps/rate-limiting/ibc_middleware.go:87 — "Revert the outflow amount" on timeout; acknowledgement error path reverts outflow at line 77 */} diff --git a/ibc/next/middleware/rate-limit-middleware/setting-limits.mdx b/ibc/next/middleware/rate-limit-middleware/setting-limits.mdx index 4cc0c79d..5c354456 100644 --- a/ibc/next/middleware/rate-limit-middleware/setting-limits.mdx +++ b/ibc/next/middleware/rate-limit-middleware/setting-limits.mdx @@ -6,16 +6,16 @@ description: >- must be executed which includes: --- -Rate limits are set through a governance-gated authority on a per denom, and per channel / client basis. To add a rate limit, the [`MsgAddRateLimit`](https://github.com/cosmos/ibc-go/blob/main/modules/apps/rate-limiting/types/msgs.go#L26-L34) message must be executed which includes: +Rate limits are set through a governance-gated authority {/* cosmos/ibc-go modules/apps/rate-limiting/keeper/msg_server.go:33 — signer must equal k.authority (the governance module address) */} on a per denom, and per channel / client basis. {/* cosmos/ibc-go modules/apps/rate-limiting/types/msgs.go:29 — Denom and ChannelOrClientId are both required fields on MsgAddRateLimit */} To add a rate limit, the [`MsgAddRateLimit`](https://github.com/cosmos/ibc-go/blob/main/modules/apps/rate-limiting/types/msgs.go#L27-L35) message must be executed which includes: -* Denom: the asset that the rate limit should be applied to -* ChannelOrClientId: the channelID for use with IBC classic connections, or the clientID for use with IBC v2 connections -* MaxPercentSend: the outflow threshold as a percentage of the `channelValue`. More explicitly, a packet being sent would exceed the threshold quota if: (Outflow - Inflow + Packet Amount) / channelValue is greater than MaxPercentSend -* MaxPercentRecv: the inflow threshold as a percentage of the `channelValue` -* DurationHours: the length of time, after which the rate limits reset +* Denom: the asset that the rate limit should be applied to {/* cosmos/ibc-go modules/apps/rate-limiting/types/msgs.go:29 */} +* ChannelOrClientId: the channelID for use with IBC classic connections, or the clientID for use with IBC v2 connections {/* cosmos/ibc-go modules/apps/rate-limiting/types/msgs.go:50 — validation accepts channel-{N} format or any valid client-id */} +* MaxPercentSend: the outflow threshold as a percentage of the `channelValue`. {/* cosmos/ibc-go modules/apps/rate-limiting/types/quota.go:18 — threshold = totalValue.Mul(q.MaxPercentSend).Quo(100) */} More explicitly, a packet being sent would exceed the threshold quota if: (Outflow - Inflow + Packet Amount) / channelValue is greater than MaxPercentSend / 100 {/* cosmos/ibc-go modules/apps/rate-limiting/types/flow.go:35 — netOutflow := f.Outflow.Sub(f.Inflow).Add(amount) */} +* MaxPercentRecv: the inflow threshold as a percentage of the `channelValue` {/* cosmos/ibc-go modules/apps/rate-limiting/types/quota.go:16 — threshold = totalValue.Mul(q.MaxPercentRecv).Quo(100) */} +* DurationHours: the length of time, after which the rate limits reset {/* cosmos/ibc-go modules/apps/rate-limiting/keeper/abci.go:8 — BeginBlocker resets rate limits whose DurationHours epoch has elapsed */} ## Updating, Removing or Resetting Rate Limits -* If rate limits were set to be too low or high for a given channel/client, they can be updated with [`MsgUpdateRateLimit`](https://github.com/cosmos/ibc-go/blob/main/modules/apps/rate-limiting/types/msgs.go#L81-L89). -* If rate limits are no longer needed, they can be removed with [`MsgRemoveRateLimit`](https://github.com/cosmos/ibc-go/blob/main/modules/apps/rate-limiting/types/msgs.go#L136-L141). -* If the flow counter needs to be resent for a given rate limit, it is possible to do so with [`MsgResetRateLimit`](https://github.com/cosmos/ibc-go/blob/main/modules/apps/rate-limiting/types/msgs.go#L169-L174). +* If rate limits were set to be too low or high for a given channel/client, they can be updated with [`MsgUpdateRateLimit`](https://github.com/cosmos/ibc-go/blob/main/modules/apps/rate-limiting/types/msgs.go#L81-L89). {/* cosmos/ibc-go modules/apps/rate-limiting/types/msgs.go:81 */} +* If rate limits are no longer needed, they can be removed with [`MsgRemoveRateLimit`](https://github.com/cosmos/ibc-go/blob/main/modules/apps/rate-limiting/types/msgs.go#L135-L140). {/* cosmos/ibc-go modules/apps/rate-limiting/types/msgs.go:135 */} +* If the flow counter needs to be reset for a given rate limit, it is possible to do so with [`MsgResetRateLimit`](https://github.com/cosmos/ibc-go/blob/main/modules/apps/rate-limiting/types/msgs.go#L167-L172). {/* cosmos/ibc-go modules/apps/rate-limiting/types/msgs.go:167 */} From 253cb3170cf17b905fad1e3fec341e49fb3883fd Mon Sep 17 00:00:00 2001 From: Evan <87997759+evanorti@users.noreply.github.com> Date: Wed, 25 Feb 2026 15:17:02 -0500 Subject: [PATCH 05/13] add /next/ --- .gitignore | 5 +- .mintignore | 4 + CLAUDE.md | 93 +- docs.json | 428 +- ibc/CLAUDE.md | 172 + ibc/next/architecture/README.mdx | 48 + .../adr-001-coin-source-tracing.mdx | 377 ++ .../adr-002-go-module-versioning.mdx | 114 + .../adr-003-ics27-acknowledgement.mdx | 122 + .../adr-004-ics29-lock-fee-module.mdx | 60 + .../adr-005-consensus-height-events.mdx | 94 + .../adr-006-02-client-refactor.mdx | 205 + .../adr-007-solomachine-signbytes.mdx | 54 + .../architecture/adr-008-app-caller-cbs.mdx | 571 +++ .../adr-009-v6-ics27-msgserver.mdx | 117 + .../adr-010-light-clients-as-sdk-modules.mdx | 108 + ...-011-transfer-total-escrow-state-entry.mdx | 147 + .../adr-015-ibc-packet-receiver.mdx | 301 ++ .../adr-025-ibc-passive-channels.mdx | 143 + ...adr-026-ibc-client-recovery-mechanisms.mdx | 92 + ibc/next/architecture/adr-027-ibc-wasm.mdx | 169 + ibc/next/architecture/adr.template.mdx | 38 + ibc/next/spec/IBC_V2/README.mdx | 204 + .../core/ics-002-client-semantics/README.mdx | 519 ++ .../core/ics-004-packet-semantics/PACKET.mdx | 172 + .../PACKET_HANDLER.mdx | 208 + .../core/ics-005-port-allocation/README.mdx | 59 + .../core/ics-024-host-requirements/README.mdx | 148 + .../ics-026-application-callbacks/README.mdx | 184 + .../README.mdx | 452 ++ .../deprecated/README.mdx | 841 ++++ .../forwarding-3-chains-failure.png | Bin 0 -> 286335 bytes .../forwarding-3-chains-success.png | Bin 0 -> 231425 bytes .../deprecated/forwarding-3-chains.excalidraw | 2425 +++++++++ .../deprecated/source-and-sink-zones.png | Bin 0 -> 171848 bytes .../ics-027-interchain-accounts/README.mdx | 826 ++++ .../ics-028-cross-chain-validation/README.mdx | 74 + .../data_structures.mdx | 340 ++ .../ccv-distribution-overview.excalidraw | 1448 ++++++ .../figures/ccv-distribution-overview.png | Bin 0 -> 314861 bytes .../figures/ccv-evidence-overview.excalidraw | 1325 +++++ .../figures/ccv-evidence-overview.png | Bin 0 -> 486533 bytes .../ccv-height-mapping-overview.excalidraw | 1661 +++++++ .../figures/ccv-height-mapping-overview.png | Bin 0 -> 705335 bytes .../figures/ccv-init-overview.excalidraw | 2987 +++++++++++ .../figures/ccv-init-overview.png | Bin 0 -> 3148100 bytes .../figures/ccv-mapping-intuition.excalidraw | 1228 +++++ .../figures/ccv-mapping-intuition.png | Bin 0 -> 81422 bytes .../ccv-preccv-init-overview.excalidraw | 2455 +++++++++ .../figures/ccv-preccv-init-overview.png | Bin 0 -> 3721251 bytes .../figures/ccv-unbonding-overview.excalidraw | 4367 +++++++++++++++++ .../figures/ccv-unbonding-overview.png | Bin 0 -> 1882490 bytes .../figures/ccv-vsc-overview.excalidraw | 946 ++++ .../figures/ccv-vsc-overview.png | Bin 0 -> 340065 bytes .../methods.mdx | 2326 +++++++++ .../overview_and_basic_concepts.mdx | 351 ++ .../system_model_and_properties.mdx | 429 ++ .../technical_specification.mdx | 137 + .../spec/app/ics-029-fee-payment/README.mdx | 605 +++ .../spec/app/ics-030-middleware/README.mdx | 372 ++ .../app/ics-031-crosschain-queries/README.mdx | 414 ++ .../spec/app/ics-100-atomic-swap/README.mdx | 660 +++ .../spec/app/ics-100-atomic-swap/ibcswap.png | Bin 0 -> 69440 bytes .../spec/app/ics-721-nft-transfer/README.mdx | 490 ++ .../spec/client/Rollup-Integration-guide.mdx | 240 + .../ics-006-solo-machine-client/README.mdx | 382 ++ .../ics-007-tendermint-client/README.mdx | 462 ++ .../client/ics-008-wasm-client/README.mdx | 582 +++ .../client/ics-009-loopback-cilent/README.mdx | 221 + .../client/ics-010-grandpa-client/README.mdx | 374 ++ .../core/ics-002-client-semantics/README.mdx | 670 +++ .../ics-003-connection-semantics/README.mdx | 610 +++ .../client-validation-removal.excalidraw | 779 +++ .../client-validation-removal.mdx | 31 + .../client-validation-removal.png | Bin 0 -> 977280 bytes .../ics-003-connection-semantics/state.png | Bin 0 -> 65287 bytes .../README.mdx | 1547 ++++++ .../UPGRADES.mdx | 1116 +++++ .../channel-state-machine.png | Bin 0 -> 91221 bytes .../channel-upgrade-flow.png | Bin 0 -> 152506 bytes .../dataflow.png | Bin 0 -> 110528 bytes .../packet-state-machine.png | Bin 0 -> 75107 bytes .../packet-transit.png | Bin 0 -> 4691495 bytes .../core/ics-005-port-allocation/README.mdx | 249 + .../ics-023-vector-commitments/README.mdx | 304 ++ .../core/ics-024-host-requirements/README.mdx | 414 ++ .../core/ics-025-handler-interface/README.mdx | 92 + .../core/ics-026-routing-module/README.mdx | 827 ++++ .../core/ics-026-routing-module/UPGRADES.mdx | 108 + .../spec/core/ics-033-multi-hop/README.mdx | 583 +++ .../ics-033-multi-hop/proof_generation.png | Bin 0 -> 87406 bytes .../core/ics-033-multi-hop/proof_query.png | Bin 0 -> 62805 bytes .../proof_query_algorithm.png | Bin 0 -> 172587 bytes .../ics-033-multi-hop/proof_verification.png | Bin 0 -> 85959 bytes .../relayer_calc_update_heights.png | Bin 0 -> 151631 bytes .../relayer_query_proof_and_submit.png | Bin 0 -> 143732 bytes ibc/next/spec/ics-001-ics-standard/README.mdx | 186 + ibc/next/spec/ics-template.md | 68 + .../ics-018-relayer-algorithms/README.mdx | 294 ++ 99 files changed, 42159 insertions(+), 95 deletions(-) create mode 100644 ibc/CLAUDE.md create mode 100644 ibc/next/architecture/README.mdx create mode 100644 ibc/next/architecture/adr-001-coin-source-tracing.mdx create mode 100644 ibc/next/architecture/adr-002-go-module-versioning.mdx create mode 100644 ibc/next/architecture/adr-003-ics27-acknowledgement.mdx create mode 100644 ibc/next/architecture/adr-004-ics29-lock-fee-module.mdx create mode 100644 ibc/next/architecture/adr-005-consensus-height-events.mdx create mode 100644 ibc/next/architecture/adr-006-02-client-refactor.mdx create mode 100644 ibc/next/architecture/adr-007-solomachine-signbytes.mdx create mode 100644 ibc/next/architecture/adr-008-app-caller-cbs.mdx create mode 100644 ibc/next/architecture/adr-009-v6-ics27-msgserver.mdx create mode 100644 ibc/next/architecture/adr-010-light-clients-as-sdk-modules.mdx create mode 100644 ibc/next/architecture/adr-011-transfer-total-escrow-state-entry.mdx create mode 100644 ibc/next/architecture/adr-015-ibc-packet-receiver.mdx create mode 100644 ibc/next/architecture/adr-025-ibc-passive-channels.mdx create mode 100644 ibc/next/architecture/adr-026-ibc-client-recovery-mechanisms.mdx create mode 100644 ibc/next/architecture/adr-027-ibc-wasm.mdx create mode 100644 ibc/next/architecture/adr.template.mdx create mode 100644 ibc/next/spec/IBC_V2/README.mdx create mode 100644 ibc/next/spec/IBC_V2/core/ics-002-client-semantics/README.mdx create mode 100644 ibc/next/spec/IBC_V2/core/ics-004-packet-semantics/PACKET.mdx create mode 100644 ibc/next/spec/IBC_V2/core/ics-004-packet-semantics/PACKET_HANDLER.mdx create mode 100644 ibc/next/spec/IBC_V2/core/ics-005-port-allocation/README.mdx create mode 100644 ibc/next/spec/IBC_V2/core/ics-024-host-requirements/README.mdx create mode 100644 ibc/next/spec/IBC_V2/core/ics-026-application-callbacks/README.mdx create mode 100644 ibc/next/spec/app/ics-020-fungible-token-transfer/README.mdx create mode 100644 ibc/next/spec/app/ics-020-fungible-token-transfer/deprecated/README.mdx create mode 100644 ibc/next/spec/app/ics-020-fungible-token-transfer/deprecated/forwarding-3-chains-failure.png create mode 100644 ibc/next/spec/app/ics-020-fungible-token-transfer/deprecated/forwarding-3-chains-success.png create mode 100644 ibc/next/spec/app/ics-020-fungible-token-transfer/deprecated/forwarding-3-chains.excalidraw create mode 100644 ibc/next/spec/app/ics-020-fungible-token-transfer/deprecated/source-and-sink-zones.png create mode 100644 ibc/next/spec/app/ics-027-interchain-accounts/README.mdx create mode 100644 ibc/next/spec/app/ics-028-cross-chain-validation/README.mdx create mode 100644 ibc/next/spec/app/ics-028-cross-chain-validation/data_structures.mdx create mode 100644 ibc/next/spec/app/ics-028-cross-chain-validation/figures/ccv-distribution-overview.excalidraw create mode 100644 ibc/next/spec/app/ics-028-cross-chain-validation/figures/ccv-distribution-overview.png create mode 100644 ibc/next/spec/app/ics-028-cross-chain-validation/figures/ccv-evidence-overview.excalidraw create mode 100644 ibc/next/spec/app/ics-028-cross-chain-validation/figures/ccv-evidence-overview.png create mode 100644 ibc/next/spec/app/ics-028-cross-chain-validation/figures/ccv-height-mapping-overview.excalidraw create mode 100644 ibc/next/spec/app/ics-028-cross-chain-validation/figures/ccv-height-mapping-overview.png create mode 100644 ibc/next/spec/app/ics-028-cross-chain-validation/figures/ccv-init-overview.excalidraw create mode 100644 ibc/next/spec/app/ics-028-cross-chain-validation/figures/ccv-init-overview.png create mode 100644 ibc/next/spec/app/ics-028-cross-chain-validation/figures/ccv-mapping-intuition.excalidraw create mode 100644 ibc/next/spec/app/ics-028-cross-chain-validation/figures/ccv-mapping-intuition.png create mode 100644 ibc/next/spec/app/ics-028-cross-chain-validation/figures/ccv-preccv-init-overview.excalidraw create mode 100644 ibc/next/spec/app/ics-028-cross-chain-validation/figures/ccv-preccv-init-overview.png create mode 100644 ibc/next/spec/app/ics-028-cross-chain-validation/figures/ccv-unbonding-overview.excalidraw create mode 100644 ibc/next/spec/app/ics-028-cross-chain-validation/figures/ccv-unbonding-overview.png create mode 100644 ibc/next/spec/app/ics-028-cross-chain-validation/figures/ccv-vsc-overview.excalidraw create mode 100644 ibc/next/spec/app/ics-028-cross-chain-validation/figures/ccv-vsc-overview.png create mode 100644 ibc/next/spec/app/ics-028-cross-chain-validation/methods.mdx create mode 100644 ibc/next/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.mdx create mode 100644 ibc/next/spec/app/ics-028-cross-chain-validation/system_model_and_properties.mdx create mode 100644 ibc/next/spec/app/ics-028-cross-chain-validation/technical_specification.mdx create mode 100644 ibc/next/spec/app/ics-029-fee-payment/README.mdx create mode 100644 ibc/next/spec/app/ics-030-middleware/README.mdx create mode 100644 ibc/next/spec/app/ics-031-crosschain-queries/README.mdx create mode 100644 ibc/next/spec/app/ics-100-atomic-swap/README.mdx create mode 100644 ibc/next/spec/app/ics-100-atomic-swap/ibcswap.png create mode 100644 ibc/next/spec/app/ics-721-nft-transfer/README.mdx create mode 100644 ibc/next/spec/client/Rollup-Integration-guide.mdx create mode 100644 ibc/next/spec/client/ics-006-solo-machine-client/README.mdx create mode 100644 ibc/next/spec/client/ics-007-tendermint-client/README.mdx create mode 100644 ibc/next/spec/client/ics-008-wasm-client/README.mdx create mode 100644 ibc/next/spec/client/ics-009-loopback-cilent/README.mdx create mode 100644 ibc/next/spec/client/ics-010-grandpa-client/README.mdx create mode 100644 ibc/next/spec/core/ics-002-client-semantics/README.mdx create mode 100644 ibc/next/spec/core/ics-003-connection-semantics/README.mdx create mode 100644 ibc/next/spec/core/ics-003-connection-semantics/client-validation-removal.excalidraw create mode 100644 ibc/next/spec/core/ics-003-connection-semantics/client-validation-removal.mdx create mode 100644 ibc/next/spec/core/ics-003-connection-semantics/client-validation-removal.png create mode 100644 ibc/next/spec/core/ics-003-connection-semantics/state.png create mode 100644 ibc/next/spec/core/ics-004-channel-and-packet-semantics/README.mdx create mode 100644 ibc/next/spec/core/ics-004-channel-and-packet-semantics/UPGRADES.mdx create mode 100644 ibc/next/spec/core/ics-004-channel-and-packet-semantics/channel-state-machine.png create mode 100644 ibc/next/spec/core/ics-004-channel-and-packet-semantics/channel-upgrade-flow.png create mode 100644 ibc/next/spec/core/ics-004-channel-and-packet-semantics/dataflow.png create mode 100644 ibc/next/spec/core/ics-004-channel-and-packet-semantics/packet-state-machine.png create mode 100644 ibc/next/spec/core/ics-004-channel-and-packet-semantics/packet-transit.png create mode 100644 ibc/next/spec/core/ics-005-port-allocation/README.mdx create mode 100644 ibc/next/spec/core/ics-023-vector-commitments/README.mdx create mode 100644 ibc/next/spec/core/ics-024-host-requirements/README.mdx create mode 100644 ibc/next/spec/core/ics-025-handler-interface/README.mdx create mode 100644 ibc/next/spec/core/ics-026-routing-module/README.mdx create mode 100644 ibc/next/spec/core/ics-026-routing-module/UPGRADES.mdx create mode 100644 ibc/next/spec/core/ics-033-multi-hop/README.mdx create mode 100644 ibc/next/spec/core/ics-033-multi-hop/proof_generation.png create mode 100644 ibc/next/spec/core/ics-033-multi-hop/proof_query.png create mode 100644 ibc/next/spec/core/ics-033-multi-hop/proof_query_algorithm.png create mode 100644 ibc/next/spec/core/ics-033-multi-hop/proof_verification.png create mode 100644 ibc/next/spec/core/ics-033-multi-hop/relayer_calc_update_heights.png create mode 100644 ibc/next/spec/core/ics-033-multi-hop/relayer_query_proof_and_submit.png create mode 100644 ibc/next/spec/ics-001-ics-standard/README.mdx create mode 100644 ibc/next/spec/ics-template.md create mode 100644 ibc/next/spec/relayer/ics-018-relayer-algorithms/README.mdx diff --git a/.gitignore b/.gitignore index 7f200c8b..855a7957 100644 --- a/.gitignore +++ b/.gitignore @@ -88,7 +88,7 @@ scripts/versioning/node_modules/ scripts/migration/node_modules/ tests/* .ingress/ -CLAUDE.md + # Markdown lint cache .md-cache @@ -102,3 +102,6 @@ CLAUDE.md # Temporary directory for link migration tracking temporary/ + +# Claude Code context and working files +WORKING.md diff --git a/.mintignore b/.mintignore index 8bbc57c6..02d29f35 100644 --- a/.mintignore +++ b/.mintignore @@ -12,3 +12,7 @@ coverage/ # Temporary directory for link migration tracking temporary/ + +# Claude Code context and working files +**/CLAUDE.md +WORKING.md diff --git a/CLAUDE.md b/CLAUDE.md index ed1aa3c9..bc52f69b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -55,19 +55,17 @@ cd tests && npm test ## Architecture & Structure ### Documentation Organization -The documentation follows a hierarchical structure configured in `docs.json`: +The documentation follows a hierarchical structure configured in `docs.json`. The repo is a multi-product docs site; each product has its own top-level directory with versioned subdirectories. -- **docs/documentation/** - Main documentation content - - `concepts/` - Core concepts (accounts, gas, transactions, IBC) - - `cosmos-sdk/` - SDK modules and protocol details - - `smart-contracts/` - Precompiles and predeployed contracts - - `integration/` - Integration guides and migration docs - - `getting-started/` - Quick start guides and tooling +#### Top-level product directories -- **docs/api-reference/** - API documentation - - `ethereum-json-rpc/` - RPC methods, OpenAPI spec, and explorer - -- **docs/changelog/** - Release notes auto-synced from cosmos/evm +- **`ibc/`** — IBC (Inter-Blockchain Communication) docs. Versions: `next/` (active), `v10.1.x`, `v8.5.x`, `v7.8.x`, `v6.3.x`, `v5.4.x`, `v4.6.x`, `v0.2.0` +- **`evm/`** — Cosmos EVM docs. Versions: `next/`, `v0.5.0`, `v0.4.x` +- **`sdk/`** — Cosmos SDK docs. Versions: `next/`, `v0.53`, `v0.50`, `v0.47` +- **`hub/`** — Cosmos Hub docs. Versions: `v25/` +- **`cometbft/`** — CometBFT docs. Versions: `v0.38/`, `v0.37/` +- **`skip-go/`** — Skip Go docs (unversioned, flat structure) +- **`enterprise/`** — Enterprise docs ### Key Technical Components @@ -106,10 +104,81 @@ When updating documentation: - **Precompile Addresses**: Fixed addresses documented in tests/README.md - **Network Endpoints**: Configure in tests/config.js for testing +## Internal Link Format + +All internal links in MDX files must use absolute root-relative paths **without** the `.mdx` extension: + +```text +✅ /sdk/next/changelog/release-notes +❌ ./release-notes.mdx +❌ ../changelog/release-notes.mdx +``` + +Mintlify resolves links by URL path, not filesystem path. Relative or extension-suffixed links will break in production. + +## File Operations Checklist + +When **adding**, **deleting**, **moving**, or **renaming** any `.mdx` file: + +1. **Update `docs.json`** — Add, remove, or update the page entry in the navigation structure. Every page must be registered to appear in the sidebar. +2. **Add redirects** — For deleted, renamed, or moved pages, add a redirect in `docs.json` so existing links and search results don't 404. +3. **Fix backlinks** — Search for all internal links pointing to the old path and update them to the new path. + +```bash +# Find broken internal links +npx mint broken-links +``` + +### Redirects in `docs.json` + +Redirects are defined as a top-level `"redirects"` array in `docs.json`. Each entry has a `source` and `destination`, both as root-relative paths without `.mdx` extensions: + +```json +"redirects": [ + { + "source": "/ibc/next/old-page-name", + "destination": "/ibc/next/new-page-name" + } +] +``` + +Wildcards are supported: + +```json +{ "source": "/ibc/beta/:slug*", "destination": "/ibc/next/:slug*" } +``` + +**Constraints:** Redirects cannot include URL anchors (`#anchor`) or query parameters (`?key=value`). Avoid circular redirects. + +### Versioning in `docs.json` and `versions.json` + +**`docs.json`** controls the version *dropdown UI* shown in the sidebar. Each product is a `dropdown` entry inside `navigation`, with a `versions` array. Each version entry contains its own `tabs`, `groups`, and `pages`: + +```json +{ + "dropdown": "IBC", + "versions": [ + { + "version": "next", + "tabs": [ ... ] + }, + { + "version": "v10.1.x", + "tabs": [ ... ] + } + ] +} +``` + +**`versions.json`** is a *custom script config* (not a Mintlify-native file). It is used by the scripts in `scripts/versioning/` to manage changelog syncing, version freezing, and related automation. It defines each product's available versions, default version, upstream GitHub repository, and changelog path. It does not affect the live docs UI directly — changes here only affect what the scripts do. + +## Session State + +`WORKING.md` in the repo root tracks active work, recent changes, and known issues for the current session. It is gitignored and mintignored. Check it at the start of any session to understand what was last being worked on. + ## Important Notes - All documentation files use MDX format with Mintlify-specific components -- Navigation structure must be updated in `docs.json` when adding new pages - Interactive RPC documentation is generated from the source `methods.mdx` file - Test findings in `tests/README.md` track documentation accuracy against implementation - Use relative imports for snippets and components (e.g., `/snippets/icons.mdx`) \ No newline at end of file diff --git a/docs.json b/docs.json index 8658da51..666c7964 100644 --- a/docs.json +++ b/docs.json @@ -1708,8 +1708,8 @@ { "group": "Core Concepts", "pages": [ - "ibc/v10.1.x/ibc/best-practices", "ibc/v10.1.x/ibc/integration", + "ibc/v10.1.x/ibc/best-practices", "ibc/v10.1.x/ibc/permissioning", "ibc/v10.1.x/ibc/relayer" ] @@ -1717,10 +1717,10 @@ { "group": "Apps", "pages": [ + "ibc/v10.1.x/ibc/apps/ibcv2apps", "ibc/v10.1.x/ibc/apps/apps", - "ibc/v10.1.x/ibc/apps/bindports", "ibc/v10.1.x/ibc/apps/ibcmodule", - "ibc/v10.1.x/ibc/apps/ibcv2apps", + "ibc/v10.1.x/ibc/apps/bindports", "ibc/v10.1.x/ibc/apps/keeper", "ibc/v10.1.x/ibc/apps/packets_acks", "ibc/v10.1.x/ibc/apps/routing", @@ -1730,19 +1730,19 @@ { "group": "Middleware", "pages": [ + "ibc/v10.1.x/ibc/middleware/overview", "ibc/v10.1.x/ibc/middleware/develop", "ibc/v10.1.x/ibc/middleware/developIBCv2", - "ibc/v10.1.x/ibc/middleware/integration", - "ibc/v10.1.x/ibc/middleware/overview" + "ibc/v10.1.x/ibc/middleware/integration" ] }, { "group": "Upgrades", "pages": [ - "ibc/v10.1.x/ibc/upgrades/developer-guide", - "ibc/v10.1.x/ibc/upgrades/genesis-restart", "ibc/v10.1.x/ibc/upgrades/intro", - "ibc/v10.1.x/ibc/upgrades/quick-guide" + "ibc/v10.1.x/ibc/upgrades/quick-guide", + "ibc/v10.1.x/ibc/upgrades/developer-guide", + "ibc/v10.1.x/ibc/upgrades/genesis-restart" ] } ] @@ -1782,32 +1782,32 @@ { "group": "Developer Guide", "pages": [ + "ibc/v10.1.x/light-clients/developer-guide/overview", + "ibc/v10.1.x/light-clients/developer-guide/light-client-module", "ibc/v10.1.x/light-clients/developer-guide/client-state", "ibc/v10.1.x/light-clients/developer-guide/consensus-state", - "ibc/v10.1.x/light-clients/developer-guide/light-client-module", - "ibc/v10.1.x/light-clients/developer-guide/overview", + "ibc/v10.1.x/light-clients/developer-guide/updates-and-misbehaviour", + "ibc/v10.1.x/light-clients/developer-guide/upgrades", "ibc/v10.1.x/light-clients/developer-guide/proofs", "ibc/v10.1.x/light-clients/developer-guide/proposals", - "ibc/v10.1.x/light-clients/developer-guide/setup", - "ibc/v10.1.x/light-clients/developer-guide/updates-and-misbehaviour", - "ibc/v10.1.x/light-clients/developer-guide/upgrades" + "ibc/v10.1.x/light-clients/developer-guide/setup" ] }, { "group": "Localhost", "pages": [ + "ibc/v10.1.x/light-clients/localhost/overview", + "ibc/v10.1.x/light-clients/localhost/integration", "ibc/v10.1.x/light-clients/localhost/client-state", "ibc/v10.1.x/light-clients/localhost/connection", - "ibc/v10.1.x/light-clients/localhost/integration", - "ibc/v10.1.x/light-clients/localhost/overview", "ibc/v10.1.x/light-clients/localhost/state-verification" ] }, { "group": "Solo Machine", "pages": [ - "ibc/v10.1.x/light-clients/solomachine/concepts", "ibc/v10.1.x/light-clients/solomachine/solomachine", + "ibc/v10.1.x/light-clients/solomachine/concepts", "ibc/v10.1.x/light-clients/solomachine/state", "ibc/v10.1.x/light-clients/solomachine/state_transitions" ] @@ -1821,15 +1821,15 @@ { "group": "WASM", "pages": [ - "ibc/v10.1.x/light-clients/wasm/client", + "ibc/v10.1.x/light-clients/wasm/overview", "ibc/v10.1.x/light-clients/wasm/concepts", - "ibc/v10.1.x/light-clients/wasm/contracts", - "ibc/v10.1.x/light-clients/wasm/events", - "ibc/v10.1.x/light-clients/wasm/governance", "ibc/v10.1.x/light-clients/wasm/integration", "ibc/v10.1.x/light-clients/wasm/messages", - "ibc/v10.1.x/light-clients/wasm/migrations", - "ibc/v10.1.x/light-clients/wasm/overview" + "ibc/v10.1.x/light-clients/wasm/governance", + "ibc/v10.1.x/light-clients/wasm/events", + "ibc/v10.1.x/light-clients/wasm/contracts", + "ibc/v10.1.x/light-clients/wasm/client", + "ibc/v10.1.x/light-clients/wasm/migrations" ] } ] @@ -1840,15 +1840,15 @@ { "group": "Interchain Accounts", "pages": [ - "ibc/v10.1.x/apps/interchain-accounts/active-channels", - "ibc/v10.1.x/apps/interchain-accounts/auth-modules", - "ibc/v10.1.x/apps/interchain-accounts/client", + "ibc/v10.1.x/apps/interchain-accounts/overview", "ibc/v10.1.x/apps/interchain-accounts/development", + "ibc/v10.1.x/apps/interchain-accounts/auth-modules", "ibc/v10.1.x/apps/interchain-accounts/integration", "ibc/v10.1.x/apps/interchain-accounts/messages", - "ibc/v10.1.x/apps/interchain-accounts/overview", "ibc/v10.1.x/apps/interchain-accounts/parameters", "ibc/v10.1.x/apps/interchain-accounts/tx-encoding", + "ibc/v10.1.x/apps/interchain-accounts/client", + "ibc/v10.1.x/apps/interchain-accounts/active-channels", { "group": "Legacy", "pages": [ @@ -1862,16 +1862,16 @@ { "group": "Transfer", "pages": [ - "ibc/v10.1.x/apps/transfer/IBCv2-transfer", - "ibc/v10.1.x/apps/transfer/authorizations", - "ibc/v10.1.x/apps/transfer/client", - "ibc/v10.1.x/apps/transfer/events", + "ibc/v10.1.x/apps/transfer/overview", + "ibc/v10.1.x/apps/transfer/state", + "ibc/v10.1.x/apps/transfer/state-transitions", "ibc/v10.1.x/apps/transfer/messages", + "ibc/v10.1.x/apps/transfer/events", "ibc/v10.1.x/apps/transfer/metrics", - "ibc/v10.1.x/apps/transfer/overview", "ibc/v10.1.x/apps/transfer/params", - "ibc/v10.1.x/apps/transfer/state", - "ibc/v10.1.x/apps/transfer/state-transitions" + "ibc/v10.1.x/apps/transfer/authorizations", + "ibc/v10.1.x/apps/transfer/client", + "ibc/v10.1.x/apps/transfer/IBCv2-transfer" ] } ] @@ -1882,20 +1882,16 @@ { "group": "Callbacks", "pages": [ - "ibc/v10.1.x/middleware/callbacks/callbacks-IBCv2", - "ibc/v10.1.x/middleware/callbacks/end-users", - "ibc/v10.1.x/middleware/callbacks/events", - "ibc/v10.1.x/middleware/callbacks/gas", + "ibc/v10.1.x/middleware/callbacks/overview", "ibc/v10.1.x/middleware/callbacks/integration", "ibc/v10.1.x/middleware/callbacks/interfaces", - "ibc/v10.1.x/middleware/callbacks/overview" + "ibc/v10.1.x/middleware/callbacks/events", + "ibc/v10.1.x/middleware/callbacks/end-users", + "ibc/v10.1.x/middleware/callbacks/gas", + "ibc/v10.1.x/middleware/callbacks/callbacks-IBCv2" ] } ] - }, - { - "group": "Security", - "pages": [] } ] }, @@ -4280,6 +4276,7 @@ { "group": "IBC Protocol", "pages": [ + "ibc/next/index", "ibc/next/intro" ] }, @@ -4299,10 +4296,10 @@ { "group": "Apps", "pages": [ + "ibc/next/ibc/apps/ibcv2apps", "ibc/next/ibc/apps/apps", - "ibc/next/ibc/apps/bindports", "ibc/next/ibc/apps/ibcmodule", - "ibc/next/ibc/apps/ibcv2apps", + "ibc/next/ibc/apps/bindports", "ibc/next/ibc/apps/keeper", "ibc/next/ibc/apps/packets_acks", "ibc/next/ibc/apps/routing", @@ -4312,19 +4309,19 @@ { "group": "Middleware", "pages": [ + "ibc/next/ibc/middleware/overview", "ibc/next/ibc/middleware/develop", "ibc/next/ibc/middleware/developIBCv2", - "ibc/next/ibc/middleware/integration", - "ibc/next/ibc/middleware/overview" + "ibc/next/ibc/middleware/integration" ] }, { "group": "Upgrades", "pages": [ - "ibc/next/ibc/upgrades/developer-guide", - "ibc/next/ibc/upgrades/genesis-restart", "ibc/next/ibc/upgrades/intro", - "ibc/next/ibc/upgrades/quick-guide" + "ibc/next/ibc/upgrades/quick-guide", + "ibc/next/ibc/upgrades/developer-guide", + "ibc/next/ibc/upgrades/genesis-restart" ] } ] @@ -4366,32 +4363,32 @@ { "group": "Developer Guide", "pages": [ + "ibc/next/light-clients/developer-guide/overview", + "ibc/next/light-clients/developer-guide/light-client-module", "ibc/next/light-clients/developer-guide/client-state", "ibc/next/light-clients/developer-guide/consensus-state", - "ibc/next/light-clients/developer-guide/light-client-module", - "ibc/next/light-clients/developer-guide/overview", + "ibc/next/light-clients/developer-guide/updates-and-misbehaviour", + "ibc/next/light-clients/developer-guide/upgrades", "ibc/next/light-clients/developer-guide/proofs", "ibc/next/light-clients/developer-guide/proposals", - "ibc/next/light-clients/developer-guide/setup", - "ibc/next/light-clients/developer-guide/updates-and-misbehaviour", - "ibc/next/light-clients/developer-guide/upgrades" + "ibc/next/light-clients/developer-guide/setup" ] }, { "group": "Localhost", "pages": [ + "ibc/next/light-clients/localhost/overview", + "ibc/next/light-clients/localhost/integration", "ibc/next/light-clients/localhost/client-state", "ibc/next/light-clients/localhost/connection", - "ibc/next/light-clients/localhost/integration", - "ibc/next/light-clients/localhost/overview", "ibc/next/light-clients/localhost/state-verification" ] }, { "group": "Solo Machine", "pages": [ - "ibc/next/light-clients/solomachine/concepts", "ibc/next/light-clients/solomachine/solomachine", + "ibc/next/light-clients/solomachine/concepts", "ibc/next/light-clients/solomachine/state", "ibc/next/light-clients/solomachine/state_transitions" ] @@ -4405,15 +4402,15 @@ { "group": "WASM", "pages": [ - "ibc/next/light-clients/wasm/client", + "ibc/next/light-clients/wasm/overview", "ibc/next/light-clients/wasm/concepts", - "ibc/next/light-clients/wasm/contracts", - "ibc/next/light-clients/wasm/events", - "ibc/next/light-clients/wasm/governance", "ibc/next/light-clients/wasm/integration", "ibc/next/light-clients/wasm/messages", - "ibc/next/light-clients/wasm/migrations", - "ibc/next/light-clients/wasm/overview" + "ibc/next/light-clients/wasm/governance", + "ibc/next/light-clients/wasm/events", + "ibc/next/light-clients/wasm/contracts", + "ibc/next/light-clients/wasm/client", + "ibc/next/light-clients/wasm/migrations" ] } ] @@ -4424,15 +4421,15 @@ { "group": "Interchain Accounts", "pages": [ - "ibc/next/apps/interchain-accounts/active-channels", - "ibc/next/apps/interchain-accounts/auth-modules", - "ibc/next/apps/interchain-accounts/client", + "ibc/next/apps/interchain-accounts/overview", "ibc/next/apps/interchain-accounts/development", + "ibc/next/apps/interchain-accounts/auth-modules", "ibc/next/apps/interchain-accounts/integration", "ibc/next/apps/interchain-accounts/messages", - "ibc/next/apps/interchain-accounts/overview", "ibc/next/apps/interchain-accounts/parameters", "ibc/next/apps/interchain-accounts/tx-encoding", + "ibc/next/apps/interchain-accounts/client", + "ibc/next/apps/interchain-accounts/active-channels", { "group": "Legacy", "pages": [ @@ -4446,16 +4443,16 @@ { "group": "Transfer", "pages": [ - "ibc/next/apps/transfer/IBCv2-transfer", - "ibc/next/apps/transfer/authorizations", - "ibc/next/apps/transfer/client", - "ibc/next/apps/transfer/events", + "ibc/next/apps/transfer/overview", + "ibc/next/apps/transfer/state", + "ibc/next/apps/transfer/state-transitions", "ibc/next/apps/transfer/messages", + "ibc/next/apps/transfer/events", "ibc/next/apps/transfer/metrics", - "ibc/next/apps/transfer/overview", "ibc/next/apps/transfer/params", - "ibc/next/apps/transfer/state", - "ibc/next/apps/transfer/state-transitions" + "ibc/next/apps/transfer/authorizations", + "ibc/next/apps/transfer/client", + "ibc/next/apps/transfer/IBCv2-transfer" ] } ] @@ -4466,18 +4463,28 @@ { "group": "Callbacks", "pages": [ - "ibc/next/middleware/callbacks/callbacks-IBCv2", - "ibc/next/middleware/callbacks/end-users", - "ibc/next/middleware/callbacks/events", - "ibc/next/middleware/callbacks/gas", + "ibc/next/middleware/callbacks/overview", "ibc/next/middleware/callbacks/integration", "ibc/next/middleware/callbacks/interfaces", - "ibc/next/middleware/callbacks/overview", - "ibc/next/middleware/packet-forward-middleware/example-usage", - "ibc/next/middleware/packet-forward-middleware/integration", + "ibc/next/middleware/callbacks/events", + "ibc/next/middleware/callbacks/end-users", + "ibc/next/middleware/callbacks/gas", + "ibc/next/middleware/callbacks/callbacks-IBCv2" + ] + }, + { + "group": "Packet Forward Middleware", + "pages": [ "ibc/next/middleware/packet-forward-middleware/overview", - "ibc/next/middleware/rate-limit-middleware/integration", + "ibc/next/middleware/packet-forward-middleware/integration", + "ibc/next/middleware/packet-forward-middleware/example-usage" + ] + }, + { + "group": "Rate Limit Middleware", + "pages": [ "ibc/next/middleware/rate-limit-middleware/overview", + "ibc/next/middleware/rate-limit-middleware/integration", "ibc/next/middleware/rate-limit-middleware/setting-limits" ] } @@ -4491,6 +4498,263 @@ } ] }, + { + "tab": "ADRs", + "groups": [ + { + "group": "Architecture Decision Records", + "pages": [ + "ibc/next/architecture/README", + "ibc/next/architecture/adr-001-coin-source-tracing", + "ibc/next/architecture/adr-002-go-module-versioning", + "ibc/next/architecture/adr-003-ics27-acknowledgement", + "ibc/next/architecture/adr-004-ics29-lock-fee-module", + "ibc/next/architecture/adr-005-consensus-height-events", + "ibc/next/architecture/adr-006-02-client-refactor", + "ibc/next/architecture/adr-007-solomachine-signbytes", + "ibc/next/architecture/adr-008-app-caller-cbs", + "ibc/next/architecture/adr-009-v6-ics27-msgserver", + "ibc/next/architecture/adr-010-light-clients-as-sdk-modules", + "ibc/next/architecture/adr-011-transfer-total-escrow-state-entry", + "ibc/next/architecture/adr-015-ibc-packet-receiver", + "ibc/next/architecture/adr-025-ibc-passive-channels", + "ibc/next/architecture/adr-026-ibc-client-recovery-mechanisms", + "ibc/next/architecture/adr-027-ibc-wasm" + ] + } + ] + }, + { + "tab": "Specs", + "groups": [ + { + "group": "IBC Specs (v1)", + "pages": [ + { + "group": "App", + "pages": [ + { + "group": "ics-020-fungible-token-transfer", + "pages": [ + "ibc/next/spec/app/ics-020-fungible-token-transfer/README", + { + "group": "deprecated", + "pages": [ + "ibc/next/spec/app/ics-020-fungible-token-transfer/deprecated/README" + ] + } + ] + }, + { + "group": "ics-027-interchain-accounts", + "pages": [ + "ibc/next/spec/app/ics-027-interchain-accounts/README" + ] + }, + { + "group": "ics-028-cross-chain-validation", + "pages": [ + "ibc/next/spec/app/ics-028-cross-chain-validation/README", + "ibc/next/spec/app/ics-028-cross-chain-validation/data_structures", + "ibc/next/spec/app/ics-028-cross-chain-validation/methods", + "ibc/next/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts", + "ibc/next/spec/app/ics-028-cross-chain-validation/system_model_and_properties", + "ibc/next/spec/app/ics-028-cross-chain-validation/technical_specification" + ] + }, + { + "group": "ics-029-fee-payment", + "pages": [ + "ibc/next/spec/app/ics-029-fee-payment/README" + ] + }, + { + "group": "ics-030-middleware", + "pages": [ + "ibc/next/spec/app/ics-030-middleware/README" + ] + }, + { + "group": "ics-031-crosschain-queries", + "pages": [ + "ibc/next/spec/app/ics-031-crosschain-queries/README" + ] + }, + { + "group": "ics-100-atomic-swap", + "pages": [ + "ibc/next/spec/app/ics-100-atomic-swap/README" + ] + }, + { + "group": "ics-721-nft-transfer", + "pages": [ + "ibc/next/spec/app/ics-721-nft-transfer/README" + ] + } + ] + }, + { + "group": "Client", + "pages": [ + "ibc/next/spec/client/Rollup-Integration-guide", + { + "group": "ics-006-solo-machine-client", + "pages": [ + "ibc/next/spec/client/ics-006-solo-machine-client/README" + ] + }, + { + "group": "ics-007-tendermint-client", + "pages": [ + "ibc/next/spec/client/ics-007-tendermint-client/README" + ] + }, + { + "group": "ics-008-wasm-client", + "pages": [ + "ibc/next/spec/client/ics-008-wasm-client/README" + ] + }, + { + "group": "ics-009-loopback-cilent", + "pages": [ + "ibc/next/spec/client/ics-009-loopback-cilent/README" + ] + }, + { + "group": "ics-010-grandpa-client", + "pages": [ + "ibc/next/spec/client/ics-010-grandpa-client/README" + ] + } + ] + }, + { + "group": "Core", + "pages": [ + { + "group": "ics-002-client-semantics", + "pages": [ + "ibc/next/spec/core/ics-002-client-semantics/README" + ] + }, + { + "group": "ics-003-connection-semantics", + "pages": [ + "ibc/next/spec/core/ics-003-connection-semantics/README", + "ibc/next/spec/core/ics-003-connection-semantics/client-validation-removal" + ] + }, + { + "group": "ics-004-channel-and-packet-semantics", + "pages": [ + "ibc/next/spec/core/ics-004-channel-and-packet-semantics/README", + "ibc/next/spec/core/ics-004-channel-and-packet-semantics/UPGRADES" + ] + }, + { + "group": "ics-005-port-allocation", + "pages": [ + "ibc/next/spec/core/ics-005-port-allocation/README" + ] + }, + { + "group": "ics-023-vector-commitments", + "pages": [ + "ibc/next/spec/core/ics-023-vector-commitments/README" + ] + }, + { + "group": "ics-024-host-requirements", + "pages": [ + "ibc/next/spec/core/ics-024-host-requirements/README" + ] + }, + { + "group": "ics-025-handler-interface", + "pages": [ + "ibc/next/spec/core/ics-025-handler-interface/README" + ] + }, + { + "group": "ics-026-routing-module", + "pages": [ + "ibc/next/spec/core/ics-026-routing-module/README", + "ibc/next/spec/core/ics-026-routing-module/UPGRADES" + ] + }, + { + "group": "ics-033-multi-hop", + "pages": [ + "ibc/next/spec/core/ics-033-multi-hop/README" + ] + } + ] + }, + { + "group": "Ics-001-ics-standard", + "pages": [ + "ibc/next/spec/ics-001-ics-standard/README" + ] + }, + { + "group": "Relayer", + "pages": [ + { + "group": "ics-018-relayer-algorithms", + "pages": [ + "ibc/next/spec/relayer/ics-018-relayer-algorithms/README" + ] + } + ] + } + ] + }, + { + "group": "IBC Specs (v2)", + "pages": [ + "ibc/next/spec/IBC_V2/README", + { + "group": "Core", + "pages": [ + { + "group": "ics-002-client-semantics", + "pages": [ + "ibc/next/spec/IBC_V2/core/ics-002-client-semantics/README" + ] + }, + { + "group": "ics-004-packet-semantics", + "pages": [ + "ibc/next/spec/IBC_V2/core/ics-004-packet-semantics/PACKET_HANDLER", + "ibc/next/spec/IBC_V2/core/ics-004-packet-semantics/PACKET" + ] + }, + { + "group": "ics-005-port-allocation", + "pages": [ + "ibc/next/spec/IBC_V2/core/ics-005-port-allocation/README" + ] + }, + { + "group": "ics-024-host-requirements", + "pages": [ + "ibc/next/spec/IBC_V2/core/ics-024-host-requirements/README" + ] + }, + { + "group": "ics-026-application-callbacks", + "pages": [ + "ibc/next/spec/IBC_V2/core/ics-026-application-callbacks/README" + ] + } + ] + } + ] + } + ] + }, { "tab": "Release Notes", "pages": [ diff --git a/ibc/CLAUDE.md b/ibc/CLAUDE.md new file mode 100644 index 00000000..2e3a53ff --- /dev/null +++ b/ibc/CLAUDE.md @@ -0,0 +1,172 @@ +# CLAUDE.md — IBC Docs Section + +This file provides guidance for working in the `ibc/` section of the IBC-docs Mintlify repo. + +## Overview + +This directory contains all IBC (Inter-Blockchain Communication) documentation for the docs site. It documents **ibc-go** — the canonical Go implementation of IBC — found at `../../../ibc-go/` (sibling repo). + +Navigation for all versions is configured in the root `docs.json`. + +## Protocol Context + +Since ibc-go v10, two protocol versions coexist in the same release: + +- **IBC Classic** — The original TAO (Transport, Authentication, Ordering) + APP layer architecture. Uses light clients, connections, channels, and ports. +- **IBC v2** — A newer, simplified protocol. Separate from Classic; a connection uses one or the other, not both. + +For IBC Eureka (the canonical IBC v2 deployment connecting Cosmos chains and Ethereum), see `../skip-go/eureka/`. + +## Versioned Structure + +| Directory | Status | +|--------------|----------------| +| `next/` | Active — work here | +| `v10.1.x/` | Frozen | +| `v8.5.x/` | Frozen | +| `v7.8.x/` | Frozen | +| `v6.3.x/` | Frozen | +| `v5.4.x/` | Frozen | +| `v4.6.x/` | Frozen | +| `v0.2.0/` | Frozen | + +**Always work in `next/`.** Frozen versions should not be edited except to fix critical errors. + +## `next/` Directory Structure + +``` +next/ +├── index.mdx # Section landing page +├── intro.mdx # IBC-Go introduction and high-level overview +├── security-audits.mdx # Security audit history +│ +├── ibc/ # Core IBC protocol (TAO layer) +│ ├── overview.mdx +│ ├── integration.mdx +│ ├── best-practices.mdx +│ ├── relayer.mdx +│ ├── permissioning.mdx +│ ├── apps/ # Building IBC application modules +│ │ ├── apps.mdx +│ │ ├── address-codec.mdx +│ │ ├── bindports.mdx +│ │ ├── ibcmodule.mdx # IBCModule interface +│ │ ├── ibcv2apps.mdx # IBCv2 app development +│ │ ├── keeper.mdx +│ │ ├── packets_acks.mdx +│ │ └── routing.mdx +│ ├── middleware/ # Writing custom middleware +│ │ ├── overview.mdx +│ │ ├── develop.mdx +│ │ ├── developIBCv2.mdx +│ │ └── integration.mdx +│ └── upgrades/ # Chain upgrade handling +│ ├── intro.mdx +│ ├── quick-guide.mdx +│ ├── developer-guide.mdx +│ └── genesis-restart.mdx +│ +├── apps/ # IBC application modules (ICS standards) +│ ├── transfer/ # ICS-20 fungible token transfer +│ │ ├── overview.mdx +│ │ ├── state.mdx +│ │ ├── state-transitions.mdx +│ │ ├── messages.mdx +│ │ ├── events.mdx +│ │ ├── params.mdx +│ │ ├── client.mdx +│ │ ├── authorizations.mdx +│ │ └── IBCv2-transfer.mdx +│ └── interchain-accounts/ # ICS-27 Interchain Accounts (ICA) +│ ├── overview.mdx +│ ├── integration.mdx +│ ├── auth-modules.mdx +│ ├── messages.mdx +│ ├── tx-encoding.mdx +│ ├── parameters.mdx +│ ├── active-channels.mdx +│ ├── client.mdx +│ ├── development.mdx +│ └── legacy/ # Legacy ICA API (pre-v7) +│ ├── auth-modules.mdx +│ ├── integration.mdx +│ └── keeper-api.mdx +│ +├── light-clients/ # Light client implementations +│ ├── proposals.mdx # Governance proposals for light clients +│ ├── tendermint/ +│ │ └── overview.mdx +│ ├── solomachine/ +│ │ ├── concepts.mdx +│ │ ├── solomachine.mdx +│ │ ├── state.mdx +│ │ └── state_transitions.mdx +│ ├── localhost/ +│ ├── wasm/ # 08-wasm light client +│ │ ├── overview.mdx +│ │ ├── concepts.mdx +│ │ ├── contracts.mdx +│ │ ├── integration.mdx +│ │ ├── governance.mdx +│ │ ├── messages.mdx +│ │ ├── events.mdx +│ │ ├── client.mdx +│ │ └── migrations.mdx +│ └── developer-guide/ # Building custom light clients +│ ├── overview.mdx +│ ├── setup.mdx +│ ├── client-state.mdx +│ ├── consensus-state.mdx +│ ├── light-client-module.mdx +│ ├── proofs.mdx +│ ├── proposals.mdx +│ ├── updates-and-misbehaviour.mdx +│ └── upgrades.mdx +│ +├── middleware/ # Middleware modules +│ ├── callbacks/ # IBC Callbacks middleware +│ │ ├── overview.mdx +│ │ ├── integration.mdx +│ │ ├── interfaces.mdx +│ │ ├── end-users.mdx +│ │ ├── gas.mdx +│ │ ├── events.mdx +│ │ └── callbacks-IBCv2.mdx +│ ├── packet-forward-middleware/ +│ │ ├── overview.mdx +│ │ ├── integration.mdx +│ │ └── example-usage.mdx +│ └── rate-limit-middleware/ +│ ├── overview.mdx +│ ├── integration.mdx +│ └── setting-limits.mdx +│ +├── migrations/ # Version migration guides +│ ├── sdk-to-v1.mdx +│ ├── v1-to-v2.mdx +│ ├── v2-to-v3.mdx +│ ├── v3-to-v4.mdx +│ ├── v4-to-v5.mdx +│ ├── v5-to-v6.mdx +│ ├── v6-to-v7.mdx +│ ├── v7-to-v7_1.mdx +│ ├── v7-to-v8.mdx +│ ├── v7_2-to-v7_3.mdx +│ ├── v8-to-v8_1.mdx +│ ├── v8_1-to-v10.mdx +│ ├── v10-to-v11.mdx +│ ├── support-denoms-with-slashes.mdx +│ ├── support-stackbuilder.mdx +│ └── migration.template.mdx # Template for new migration guides +│ +└── changelog/ + └── release-notes.mdx # Release notes (auto-synced from cosmos/ibc-go) +``` + +## Key Notes + +- **Navigation**: All pages must be registered in the root `docs.json` to appear in the sidebar. Adding a new file without updating `docs.json` will make it unreachable. +- **IBCv2 content**: Many sections have parallel IBCv2 pages (e.g., `ibcv2apps.mdx`, `callbacks-IBCv2.mdx`, `IBCv2-transfer.mdx`). Keep Classic and v2 docs in sync when updating. +- **Legacy ICA**: The `apps/interchain-accounts/legacy/` subdirectory documents the pre-v7 ICA API. Do not update these files; they are frozen references. +- **Changelogs**: `changelog/release-notes.mdx` is managed by the versioning scripts in `../scripts/versioning/`. Don't edit it manually. +- **Images**: Shared images are in `../images/` (sibling to `next/`). diff --git a/ibc/next/architecture/README.mdx b/ibc/next/architecture/README.mdx new file mode 100644 index 00000000..05760b6d --- /dev/null +++ b/ibc/next/architecture/README.mdx @@ -0,0 +1,48 @@ +--- +sidebar_position: 1 +--- + +# Architecture Decision Records (ADR) + +This is a location to record all high-level architecture decisions in the ibc-go project. + +You can read more about the ADR concept in this [blog post](https://product.reverb.com/documenting-architecture-decisions-the-reverb-way-a3563bb24bd0#.78xhdix6t). + +An ADR should provide: + +- Context on the relevant goals and the current state +- Proposed changes to achieve the goals +- Summary of pros and cons +- References +- Changelog + +Note the distinction between an ADR and a spec. The ADR provides the context, intuition, reasoning, and +justification for a change in architecture, or for the architecture of something +new. The spec is much more compressed and streamlined summary of everything as +it is or should be. + +If recorded decisions turned out to be lacking, convene a discussion, record the new decisions here, and then modify the code to match. + +Note the context/background should be written in the present tense. + +To suggest an ADR, please make use of the [ADR template](https://github.com/cosmos/ibc-go/blob/main/docs/architecture/adr.template.md) provided. + +## Table of Contents + +| ADR \# | Description | Status | +| ------ | ----------- | ------ | +| [001](/ibc/next/architecture/adr-001-coin-source-tracing) | ICS-20 coin denomination format | Accepted, Implemented | +| [002](/ibc/next/architecture/adr-002-go-module-versioning) | Go module versioning | Accepted | +| [003](/ibc/next/architecture/adr-003-ics27-acknowledgement) | ICS27 acknowledgement format | Accepted | +| [004](/ibc/next/architecture/adr-004-ics29-lock-fee-module) | ICS29 module locking upon escrow out of balance | Accepted | +| [005](/ibc/next/architecture/adr-005-consensus-height-events) | `UpdateClient` events - `ClientState` consensus heights | Accepted | +| [006](/ibc/next/architecture/adr-006-02-client-refactor) | ICS02 client refactor | Accepted | +| [007](/ibc/next/architecture/adr-007-solomachine-signbytes) | ICS06 Solo machine sign bytes | Accepted | +| [008](/ibc/next/architecture/adr-008-app-caller-cbs) | Callback to IBC Actors | Accepted | +| [009](/ibc/next/architecture/adr-009-v6-ics27-msgserver) | ICS27 message server addition | Accepted | +| [010](/ibc/next/architecture/adr-010-light-clients-as-sdk-modules) | IBC light clients as SDK modules | Accepted | +| [011](/ibc/next/architecture/adr-011-transfer-total-escrow-state-entry) | ICS20 state entry for total amount of tokens in escrow | Accepted | +| [015](/ibc/next/architecture/adr-015-ibc-packet-receiver) | IBC Packet Routing | Accepted | +| [025](/ibc/next/architecture/adr-025-ibc-passive-channels) | IBC passive channels | Deprecated | +| [026](/ibc/next/architecture/adr-026-ibc-client-recovery-mechanisms) | IBC client recovery mechanisms | Accepted | +| [027](/ibc/next/architecture/adr-027-ibc-wasm) | Wasm based light clients | Accepted | diff --git a/ibc/next/architecture/adr-001-coin-source-tracing.mdx b/ibc/next/architecture/adr-001-coin-source-tracing.mdx new file mode 100644 index 00000000..a4eb4e47 --- /dev/null +++ b/ibc/next/architecture/adr-001-coin-source-tracing.mdx @@ -0,0 +1,377 @@ +--- +title: "ADR 001: Coin Source Tracing" +--- + +## Changelog + +- 09-07-2020: Initial Draft +- 11-08-2020: Implementation changes + +## Status + +Accepted, Implemented + +## Context + +The specification for IBC cross-chain fungible token transfers +([ICS20](https://github.com/cosmos/ibc/tree/master/spec/app/ics-020-fungible-token-transfer)), needs to +be aware of the origin of any token denomination in order to relay a `Packet` which contains the sender +and recipient addresses in the +[`FungibleTokenPacketData`](https://github.com/cosmos/ibc/tree/master/spec/app/ics-020-fungible-token-transfer#data-structures). + +The Packet relay sending works based in 2 cases (per +[specification](https://github.com/cosmos/ibc/tree/master/spec/app/ics-020-fungible-token-transfer#packet-relay) and [Colin Axnér](https://github.com/colin-axner)'s description): + +1. Sender chain is acting as the source zone. The coins are transferred +to an escrow address (i.e locked) on the sender chain and then transferred +to the receiving chain through IBC TAO logic. It is expected that the +receiving chain will mint vouchers to the receiving address. + +2. Sender chain is acting as the sink zone. The coins (vouchers) are burned +on the sender chain and then transferred to the receiving chain through IBC +TAO logic. It is expected that the receiving chain, which had previously +sent the original denomination, will unescrow the fungible token and send +it to the receiving address. + +Another way of thinking of source and sink zones is through the token's +timeline. Each send to any chain other than the one it was previously +received from is a movement forwards in the token's timeline. This causes +trace to be added to the token's history and the destination port and +destination channel to be prefixed to the denomination. In these instances +the sender chain is acting as the source zone. When the token is sent back +to the chain it previously received from, the prefix is removed. This is +a backwards movement in the token's timeline and the sender chain +is acting as the sink zone. + +### Example + +Assume the following channel connections exist and that all channels use the port ID `transfer`: + +- chain `A` has channels with chain `B` and chain `C` with the IDs `channelToB` and `channelToC`, respectively +- chain `B` has channels with chain `A` and chain `C` with the IDs `channelToA` and `channelToC`, respectively +- chain `C` has channels with chain `A` and chain `B` with the IDs `channelToA` and `channelToB`, respectively + +These steps of transfer between chains occur in the following order: `A -> B -> C -> A -> C`. In particular: + +1. `A -> B`: sender chain is source zone. `A` sends packet with `denom` (escrowed on `A`), `B` receives `denom` and mints and sends voucher `transfer/channelToA/denom` to recipient. +2. `B -> C`: sender chain is source zone. `B` sends packet with `transfer/channelToA/denom` (escrowed on `B`), `C` receives `transfer/channelToA/denom` and mints and sends voucher `transfer/channelToB/transfer/channelToA/denom` to recipient. +3. `C -> A`: sender chain is source zone. `C` sends packet with `transfer/channelToB/transfer/channelToA/denom` (escrowed on `C`), `A` receives `transfer/channelToB/transfer/channelToA/denom` and mints and sends voucher `transfer/channelToC/transfer/channelToB/transfer/channelToA/denom` to recipient. +4. `A -> C`: sender chain is sink zone. `A` sends packet with `transfer/channelToC/transfer/channelToB/transfer/channelToA/denom` (burned on `A`), `C` receives `transfer/channelToC/transfer/channelToB/transfer/channelToA/denom`, and unescrows and sends `transfer/channelToB/transfer/channelToA/denom` to recipient. + +The token has a final denomination on chain `C` of `transfer/channelToB/transfer/channelToA/denom`, where `transfer/channelToB/transfer/channelToA` is the trace information. + +In this context, upon a receive of a cross-chain fungible token transfer, if the sender chain is the source of the token, the protocol prefixes the denomination with the port and channel identifiers in the following format: + +```typescript +prefix + denom = {destPortN}/{destChannelN}/.../{destPort0}/{destChannel0}/denom +``` + +Example: transferring `100 uatom` from port `HubPort` and channel `HubChannel` on the Hub to +Ethermint's port `EthermintPort` and channel `EthermintChannel` results in `100 +EthermintPort/EthermintChannel/uatom`, where `EthermintPort/EthermintChannel/uatom` is the new +denomination on the receiving chain. + +In the case those tokens are transferred back to the Hub (i.e the **source** chain), the prefix is +trimmed and the token denomination updated to the original one. + +### Problem + +The problem of adding additional information to the coin denomination is twofold: + +1. The ever increasing length if tokens are transferred to zones other than the source: + +If a token is transferred `n` times via IBC to a sink chain, the token denom will contain `n` pairs +of prefixes, as shown on the format example above. This poses a problem because, while port and +channel identifiers have a maximum length of 64 each, the SDK `Coin` type only accepts denoms up to +64 characters. Thus, a single cross-chain token, which again, is composed by the port and channels +identifiers plus the base denomination, can exceed the length validation for the SDK `Coins`. + +This can result in undesired behaviours such as tokens not being able to be transferred to multiple +sink chains if the denomination exceeds the length or unexpected `panics` due to denomination +validation failing on the receiving chain. + +2. The existence of special characters and uppercase letters on the denomination: + +In the SDK every time a `Coin` is initialized through the constructor function `NewCoin`, a validation +of a coin's denom is performed according to a +[Regex](https://github.com/cosmos/cosmos-sdk/blob/a940214a4923a3bf9a9161cd14bd3072299cd0c9/types/coin.go#L583), +where only lowercase alphanumeric characters are accepted. While this is desirable for native denominations +to keep a clean UX, it presents a challenge for IBC as ports and channels might be randomly +generated with special and uppercase characters as per the [ICS 024 - Host +Requirements](https://github.com/cosmos/ibc/tree/master/spec/core/ics-024-host-requirements#paths-identifiers-separators) +specification. + +## Decision + +The issues outlined above, are applicable only to SDK-based chains, and thus the proposed solution +are do not require specification changes that would result in modification to other implementations +of the ICS20 spec. + +Instead of adding the identifiers on the coin denomination directly, the proposed solution hashes +the denomination prefix in order to get a consistent length for all the cross-chain fungible tokens. + +This will be used for internal storage only, and when transferred via IBC to a different chain, the +denomination specified on the packed data will be the full prefix path of the identifiers needed to +trace the token back to the originating chain, as specified on ICS20. + +The new proposed format will be the following: + +```go +ibcDenom = "ibc/" + hash(trace path + "/" + base denom) +``` + +The hash function will be a SHA256 hash of the fields of the `DenomTrace`: + +```protobuf +// DenomTrace contains the base denomination for ICS20 fungible tokens and the source tracing +// information +message DenomTrace { + // chain of port/channel identifiers used for tracing the source of the fungible token + string path = 1; + // base denomination of the relayed fungible token + string base_denom = 2; +} +``` + +The `IBCDenom` function constructs the `Coin` denomination used when creating the ICS20 fungible token packet data: + +```go +// Hash returns the hex bytes of the SHA256 hash of the DenomTrace fields using the following formula: +// +// hash = sha256(tracePath + "/" + baseDenom) +func (dt DenomTrace) Hash() tmbytes.HexBytes { + return tmhash.Sum(dt.Path + "/" + dt.BaseDenom) +} + +// IBCDenom a coin denomination for an ICS20 fungible token in the format 'ibc/{hash(tracePath + baseDenom)}'. +// If the trace is empty, it will return the base denomination. +func (dt DenomTrace) IBCDenom() string { + if dt.Path != "" { + return fmt.Sprintf("ibc/%s", dt.Hash()) + } + return dt.BaseDenom +} +``` + +### `x/ibc-transfer` Changes + +In order to retrieve the trace information from an IBC denomination, a lookup table needs to be +added to the `ibc-transfer` module. These values need to also be persisted between upgrades, meaning +that a new `[]DenomTrace` `GenesisState` field state needs to be added to the module: + +```go +// GetDenomTrace retrieves the full identifiers trace and base denomination from the store. +func (k Keeper) GetDenomTrace(ctx Context, denomTraceHash []byte) (DenomTrace, bool) { + store := ctx.KVStore(k.storeKey) + bz := store.Get(types.KeyDenomTrace(traceHash)) + if bz == nil { + return &DenomTrace, false + } + + var denomTrace DenomTrace + k.cdc.MustUnmarshalBinaryBare(bz, &denomTrace) + return denomTrace, true +} + +// HasDenomTrace checks if a the key with the given trace hash exists on the store. +func (k Keeper) HasDenomTrace(ctx Context, denomTraceHash []byte) bool { + store := ctx.KVStore(k.storeKey) + return store.Has(types.KeyTrace(denomTraceHash)) +} + +// SetDenomTrace sets a new {trace hash -> trace} pair to the store. +func (k Keeper) SetDenomTrace(ctx Context, denomTrace DenomTrace) { + store := ctx.KVStore(k.storeKey) + bz := k.cdc.MustMarshalBinaryBare(&denomTrace) + store.Set(types.KeyTrace(denomTrace.Hash()), bz) +} +``` + +The `MsgTransfer` will validate that the `Coin` denomination from the `Token` field contains a valid +hash, if the trace info is provided, or that the base denominations matches: + +```go +func (msg MsgTransfer) ValidateBasic() error { + // ... + return ValidateIBCDenom(msg.Token.Denom) +} +``` + +```go +// ValidateIBCDenom validates that the given denomination is either: +// +// - A valid base denomination (eg: 'uatom') +// - A valid fungible token representation (i.e 'ibc/{hash}') per ADR 001 https://github.com/cosmos/ibc-go/blob/main/docs/architecture/adr-001-coin-source-tracing.md +func ValidateIBCDenom(denom string) error { + denomSplit := strings.SplitN(denom, "/", 2) + + switch { + case strings.TrimSpace(denom) == "", + len(denomSplit) == 1 && denomSplit[0] == "ibc", + len(denomSplit) == 2 && (denomSplit[0] != "ibc" || strings.TrimSpace(denomSplit[1]) == ""): + return sdkerrors.Wrapf(ErrInvalidDenomForTransfer, "denomination should be prefixed with the format 'ibc/{hash(trace + \"/\" + %s)}'", denom) + + case denomSplit[0] == denom && strings.TrimSpace(denom) != "": + return sdk.ValidateDenom(denom) + } + + if _, err := ParseHexHash(denomSplit[1]); err != nil { + return Wrapf(err, "invalid denom trace hash %s", denomSplit[1]) + } + + return nil +} +``` + +The denomination trace info only needs to be updated when token is received: + +- Receiver is **source** chain: The receiver created the token and must have the trace lookup already stored (if necessary *ie* native token case wouldn't need a lookup). +- Receiver is **not source** chain: Store the received info. For example, during step 1, when chain `B` receives `transfer/channelToA/denom`. + +```go +// SendTransfer +// ... + + fullDenomPath := token.Denom + +// deconstruct the token denomination into the denomination trace info +// to determine if the sender is the source chain +if strings.HasPrefix(token.Denom, "ibc/") { + fullDenomPath, err = k.DenomPathFromHash(ctx, token.Denom) + if err != nil { + return err + } +} + +if types.SenderChainIsSource(sourcePort, sourceChannel, fullDenomPath) { +//... +``` + +```go +// DenomPathFromHash returns the full denomination path prefix from an ibc denom with a hash +// component. +func (k Keeper) DenomPathFromHash(ctx sdk.Context, denom string) (string, error) { + hexHash := denom[4:] + hash, err := ParseHexHash(hexHash) + if err != nil { + return "", Wrap(ErrInvalidDenomForTransfer, err.Error()) + } + + denomTrace, found := k.GetDenomTrace(ctx, hash) + if !found { + return "", Wrap(ErrTraceNotFound, hexHash) + } + + fullDenomPath := denomTrace.GetFullDenomPath() + return fullDenomPath, nil +} +``` + +```go +// OnRecvPacket +// ... + +// This is the prefix that would have been prefixed to the denomination +// on sender chain IF and only if the token originally came from the +// receiving chain. +// +// NOTE: We use SourcePort and SourceChannel here, because the counterparty +// chain would have prefixed with DestPort and DestChannel when originally +// receiving this coin as seen in the "sender chain is the source" condition. +if ReceiverChainIsSource(packet.GetSourcePort(), packet.GetSourceChannel(), data.Denom) { + // sender chain is not the source, unescrow tokens + + // remove prefix added by sender chain + voucherPrefix := types.GetDenomPrefix(packet.GetSourcePort(), packet.GetSourceChannel()) + unprefixedDenom := data.Denom[len(voucherPrefix):] + token := sdk.NewCoin(unprefixedDenom, sdk.NewIntFromUint64(data.Amount)) + + // unescrow tokens + escrowAddress := types.GetEscrowAddress(packet.GetDestPort(), packet.GetDestChannel()) + return k.bankKeeper.SendCoins(ctx, escrowAddress, receiver, sdk.NewCoins(token)) +} + +// sender chain is the source, mint vouchers + +// since SendPacket did not prefix the denomination, we must prefix denomination here +sourcePrefix := types.GetDenomPrefix(packet.GetDestPort(), packet.GetDestChannel()) +// NOTE: sourcePrefix contains the trailing "/" +prefixedDenom := sourcePrefix + data.Denom + +// construct the denomination trace from the full raw denomination +denomTrace := types.ParseDenomTrace(prefixedDenom) + +// set the value to the lookup table if not stored already +traceHash := denomTrace.Hash() +if !k.HasDenomTrace(ctx, traceHash) { + k.SetDenomTrace(ctx, traceHash, denomTrace) +} + +voucherDenom := denomTrace.IBCDenom() +voucher := sdk.NewCoin(voucherDenom, sdk.NewIntFromUint64(data.Amount)) + +// mint new tokens if the source of the transfer is the same chain +if err := k.bankKeeper.MintCoins( + ctx, types.ModuleName, sdk.NewCoins(voucher), +); err != nil { + return err +} + +// send to receiver +return k.bankKeeper.SendCoinsFromModuleToAccount( + ctx, types.ModuleName, receiver, sdk.NewCoins(voucher), +) +``` + +```go +func NewDenomTraceFromRawDenom(denom string) DenomTrace{ + denomSplit := strings.Split(denom, "/") + trace := "" + if len(denomSplit) > 1 { + trace = strings.Join(denomSplit[:len(denomSplit)-1], "/") + } + return DenomTrace{ + BaseDenom: denomSplit[len(denomSplit)-1], + Trace: trace, + } +} +``` + +One final remark is that the `FungibleTokenPacketData` will remain the same, i.e with the prefixed full denomination, since the receiving chain may not be an SDK-based chain. + +### Coin Changes + +The coin denomination validation will need to be updated to reflect these changes. In particular, the denomination validation +function will now: + +- Accept slash separators (`"/"`) and uppercase characters (due to the `HexBytes` format) +- Bump the maximum character length to 128, as the hex representation used by Tendermint's + `HexBytes` type contains 64 characters. + +Additional validation logic, such as verifying the length of the hash, the may be added to the bank module in the future if the [custom base denomination validation](https://github.com/cosmos/cosmos-sdk/pull/6755) is integrated into the SDK. + +### Positive + +- Clearer separation of the source tracing behaviour of the token (transfer prefix) from the original + `Coin` denomination +- Consistent validation of `Coin` fields (i.e no special characters, fixed max length) +- Cleaner `Coin` and standard denominations for IBC +- No additional fields to SDK `Coin` + +### Negative + +- Store each set of tracing denomination identifiers on the `ibc-transfer` module store +- Clients will have to fetch the base denomination every time they receive a new relayed fungible token over IBC. This can be mitigated using a map/cache for already seen hashes on the client side. Other forms of mitigation, would be opening a websocket connection subscribe to incoming events. + +### Neutral + +- Slight difference with the ICS20 spec +- Additional validation logic for IBC coins on the `ibc-transfer` module +- Additional genesis fields +- Slightly increases the gas usage on cross-chain transfers due to access to the store. This should + be inter-block cached if transfers are frequent. + +## References + +- [ICS 20 - Fungible token transfer](https://github.com/cosmos/ibc/tree/master/spec/app/ics-020-fungible-token-transfer) +- [Custom Coin Denomination validation](https://github.com/cosmos/cosmos-sdk/pull/6755) diff --git a/ibc/next/architecture/adr-002-go-module-versioning.mdx b/ibc/next/architecture/adr-002-go-module-versioning.mdx new file mode 100644 index 00000000..0be09356 --- /dev/null +++ b/ibc/next/architecture/adr-002-go-module-versioning.mdx @@ -0,0 +1,114 @@ +--- +title: "ADR 002: Go Module Versioning" +--- + +## Changelog + +- 05-01-2022: initial draft + +## Status + +Accepted + +## Context + +The IBC module was originally developed in the Cosmos SDK and released during the Stargate release series (v0.42). +It was subsequently migrated to its own repository, ibc-go. +The first official release on ibc-go was v1.0.0. +v1.0.0 was decided to be used instead of v0.1.0 primarily for the following reasons: + +- Maintaining compatibility with the IBC specification v1 requires stronger support/guarantees. +- Using the major, minor, and patch numbers allows for easier communication of what breaking changes are included in a release. +- The IBC module is being used by numerous high value projects which require stability. + +### Problems + +#### Go module version must be incremented + +When a Go module is released under v1.0.0, all following releases must follow Go semantic versioning. +Thus when the go API is broken, the Go module major version **must** be incremented. +For example, changing the go package version from `v2` to `v3` bumps the import from `github.com/cosmos/ibc-go/v2` to `github.com/cosmos/ibc-go/v3`. + +If the Go module version is not incremented then attempting to go get a module @v3.0.0 without the suffix results in: +`invalid version: module contains a go.mod file, so major version must be compatible: should be v0 or v1, not v3` + +Version validation was added in Go 1.13. This means that in order to release a v3.0.0 git tag without a /v3 suffix on the module definition, the tag must explicitly **not** contain a go.mod file. +Not including a go.mod in our release is not a viable option. + +#### Attempting to import multiple go module versions for ibc-go + +Attempting to import two versions of ibc-go, such as `github.com/cosmos/ibc-go/v2` and `github.com/cosmos/ibc-go/v3`, will result in multiple issues. + +The Cosmos SDK does global registration of error and governance proposal types. +The errors and proposals used in ibc-go would need to now register their naming based on the go module version. + +The more concerning problem is that protobuf definitions will also reach a namespace collision. +ibc-go and the Cosmos SDK in general rely heavily on using extended functions for go structs generated from protobuf definitions. +This requires the go structs to be defined in the same package as the extended functions. +Thus, bumping the import versioning causes the protobuf definitions to be generated in two places (in v2 and v3). +When registering these types at compile time, the go compiler will panic. +The generated types need to be registered against the proto codec, but there exist two definitions for the same name. + +The protobuf conflict policy can be overridden via the environment variable `GOLANG_PROTOBUF_REGISTRATION_CONFLICT`, but it is possible this could lead to various runtime errors or unexpected behaviour (see [here](https://github.com/protocolbuffers/protobuf-go/blob/master/reflect/protoregistry/registry.go#L46)). +More information [here](https://developers.google.com/protocol-buffers/docs/reference/go/faq#namespace-conflict) on namespace conflicts for protobuf versioning. + +### Potential solutions + +#### Changing the protobuf definition version + +The protobuf definitions all have a type URL containing the protobuf version for this type. +Changing the protobuf version would solve the namespace collision which arise from importing multiple versions of ibc-go, but it leads to new issues. + +In the Cosmos SDK, `Any`s are unpacked and decoded using the type URL. +Changing the type URL thus is creating a distinctly different type. +The same registration on the proto codec cannot be used to unpack the new type. +For example: + +All Cosmos SDK messages are packed into `Any`s. If we incremented the protobuf version for our IBC messages, clients which submitted the v1 of our Cosmos SDK messages would now be rejected since the old type is not registered on the codec. +The clients must know to submit the v2 of these messages. This pushes the burden of versioning onto relayers and wallets. + +A more serious problem is that the `ClientState` and `ConsensusState` are packed as `Any`s. Changing the protobuf versioning of these types would break compatibility with IBC specification v1. + +#### Moving protobuf definitions to their own go module + +The protobuf definitions could be moved to their own go module which uses 0.x versioning and will never go to 1.0. +This prevents the Go module version from being incremented with breaking changes. +It also requires all extended functions to live in the same Go module, disrupting the existing code structure. + +The version that implements this change will still be incompatible with previous versions, but future versions could be imported together without namespace collisions. +For example, let's say this solution is implemented in v3. Then + +`github.com/cosmos/ibc-go/v2` cannot be imported with any other ibc-go version + +`github.com/cosmos/ibc-go/v3` cannot be imported with any previous ibc-go versions + +`github.com/cosmos/ibc-go/v4` may be imported with ibc-go versions v3+ + +`github.com/cosmos/ibc-go/v5` may be imported with ibc-go versions v3+ + +## Decision + +Supporting importing multiple versions of ibc-go requires a non-trivial amount of complexity. +It is unclear when a user of the ibc-go code would need multiple versions of ibc-go. +Until there is an overwhelming reason to support importing multiple versions of ibc-go: + +**Major releases cannot be imported simultaneously**. +Releases should focus on keeping backwards compatibility for go code clients, within reason. +Old functionality should be marked as deprecated and there should exist upgrade paths between major versions. +Deprecated functionality may be removed when no clients rely on that functionality. +How this is determined is to be decided. + +**Error and proposal type registration will not be changed between go module version increments**. +This explicitly stops external clients from trying to import two major versions (potentially risking a bug due to the instability of proto name collisions override). + +## Consequences + +This only affects clients relying directly on the go code. + +### Positive + +### Negative + +Multiple ibc-go versions cannot be imported. + +### Neutral diff --git a/ibc/next/architecture/adr-003-ics27-acknowledgement.mdx b/ibc/next/architecture/adr-003-ics27-acknowledgement.mdx new file mode 100644 index 00000000..0865e53b --- /dev/null +++ b/ibc/next/architecture/adr-003-ics27-acknowledgement.mdx @@ -0,0 +1,122 @@ +--- +title: "ADR 003: ICS-27 Acknowledgement Format" +--- + +## Changelog + +- 28-01-2022: Initial Draft + +## Status + +Accepted + +## Context + +Upon receiving an IBC packet, an IBC application can optionally return an acknowledgement. +This acknowledgement will be hashed and written into state. Thus any changes to the information included in an acknowledgement are state machine breaking. + +ICS27 executes transactions on behalf of a controller chain. Information such as the message result or message error may be returned from other SDK modules outside the control of the ICS27 module. +It might be very valuable to return message execution information inside the ICS27 acknowledgement so that controller chain interchain account auth modules can act upon this information. +Only deterministic information returned from the message execution is allowed to be returned in the packet acknowledgement otherwise the network will halt due to a fork in the expected app hash. + +## Decision + +At the time of this writing, Tendermint includes the following information in the [ABCI.ResponseDeliverTx](https://github.com/tendermint/tendermint/blob/release/v0.34.13/types/results.go#L47-#L53): + +```go +// deterministicResponseDeliverTx strips non-deterministic fields from +// ResponseDeliverTx and returns another ResponseDeliverTx. +func deterministicResponseDeliverTx(response *abci.ResponseDeliverTx) *abci.ResponseDeliverTx { + return &abci.ResponseDeliverTx{ + Code: response.Code, + Data: response.Data, + GasWanted: response.GasWanted, + GasUsed: response.GasUsed, + } +} +``` + +### Successful acknowledgements + +Successful acknowledgements should return information about the transaction execution. +Given the deterministic fields in the `abci.ResponseDeliverTx`, the transaction `Data` can be used to indicate information about the transaction execution. +The `abci.ResponseDeliverTx.Data` will be set in the ICS27 packet acknowledgement upon successful transaction execution. + +The format for the `abci.ResponseDeliverTx.Data` is constructed by the SDK. + +At the time of this writing, the next major release of the SDK will change the format for constructing the transaction response data. + +#### v0.45 format + +The current version, v0.45 constructs the transaction response as follows: + +```go +proto.Marshal(&sdk.TxMsgData{ + Data: []*sdk.MsgData{msgResponses...}, +} +``` + +Where `msgResponses` is a slice of `*sdk.MsgData`. +The `MsgData.MsgType` contains the `sdk.MsgTypeURL` of the `sdk.Msg` being executed. +The `MsgData.Data` contains the proto marshaled `MsgResponse` for the associated message executed. + +#### Next major version format + +The next major version will construct the transaction response as follows: + +```go +proto.Marshal(&sdk.TxMsgData{ + MsgResponses: []*codectypes.Any{msgResponses...}, +} +``` + +Where `msgResponses` is a slice of the `MsgResponse`s packed into `Any`s. + +#### Forwards compatible approach + +A forwards compatible approach was deemed infeasible. +The `handler` provided by the `MsgServiceRouter` will only include the `*sdk.Result` and an error (if one occurred). +In v0.45 of the SDK, the `*sdk.Result.Data` will contain the MsgResponse marshaled data. +However, the MsgResponse is not packed and marshaled as a `*codectypes.Any`, thus making it impossible from a generalized point of view to unmarshal the bytes. +If the bytes could be unmarshaled, then they could be packed into an `*codectypes.Any` in anticipation of the upcoming format. + +Intercepting the MsgResponse before it becomes marshaled requires replicating this [code](https://github.com/cosmos/cosmos-sdk/blob/dfd47f5b449f558a855da284a9a7eabbfbad435d/baseapp/msg_service_router.go#L109-#L128). +It may not even be possible to replicate the linked code. The method handler would need to be accessed somehow. + +For these reasons it is deemed infeasible to attempt a forwards compatible approach. + +ICA auth developers can interpret which format was used when constructing the transaction response by checking if the `sdk.TxMsgData.Data` field is non-empty. +If the `sdk.TxMsgData.Data` field is not empty then the format for v0.45 was used, otherwise ICA auth developers can assume the transaction response uses the newer format. + +#### Decision + +Replicate the transaction response format as provided by the current SDK version. +When the SDK version changes, adjust the transaction response format to use the updated transaction response format. +Include the transaction response bytes in the result channel acknowledgement. + +A test has been [written](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/host/ibc_module_test.go#L716-#L774) to fail if the `MsgResponse` is no longer included in consensus. + +### Error acknowledgements + +As indicated above, the `abci.ResponseDeliverTx.Code` is deterministic. +Upon transaction execution errors, an error acknowledgement should be returned including the abci code. + +A test has been [written](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/apps/27-interchain-accounts/host/types/ack_test.go#L41-#L82) to fail if the ABCI code is no longer deterministic. + +## Consequences + +> This section describes the consequences, after applying the decision. All consequences should be summarized here, not just the "positive" ones. + +### Positive + +- interchain account auth modules can act upon transaction results without requiring a query module +- transaction results align with those returned by execution of a normal SDK message. + +### Negative + +- the security assumptions of this decision rest on the inclusion of the ABCI error code and the Msg response in the ResponseDeliverTx hash created by Tendermint +- events are non-deterministic and cannot be included in the packet acknowledgement + +### Neutral + +No neutral consequences. diff --git a/ibc/next/architecture/adr-004-ics29-lock-fee-module.mdx b/ibc/next/architecture/adr-004-ics29-lock-fee-module.mdx new file mode 100644 index 00000000..5b4059ae --- /dev/null +++ b/ibc/next/architecture/adr-004-ics29-lock-fee-module.mdx @@ -0,0 +1,60 @@ +--- +title: "ADR 004: Lock Fee Module Upon Escrow Out Of Balance" +--- + +## Changelog + +- 03-03-2022: initial draft + +## Status + +Accepted + +## Context + +The fee module maintains an escrow account for all fees escrowed to incentivize packet relays. +It also tracks each packet fee escrowed separately from the escrow account. This is because the escrow account only maintains a total balance. It has no reference for which coins belonged to which packet fee. +In the presence of a severe bug, it is possible the escrow balance will become out of sync with the packet fees marked as escrowed. +The ICS29 module should be capable of elegantly handling such a scenario. + +## Decision + +We will allow for the ICS29 module to become "locked" if the escrow balance is determined to be out of sync with the packet fees marked as escrowed. +A "locked" fee module will not allow for packet escrows to occur nor will it distribute fees. All IBC callbacks will skip performing fee logic, similar to fee disabled channels. + +Manual intervention will be needed to unlock the fee module. + +### Sending side + +Special behaviour will have to be accounted for in `OnAcknowledgementPacket`. Since the counterparty will continue to send incentivized acknowledgements for fee enabled channels, the acknowledgement will still need to be unmarshalled into an incentivized acknowledgement before calling the underlying application `OnAcknowledgePacket` callback. + +When distributing fees, a cached context should be used. If the escrow account balance would become negative, the current state changes should be discarded and the fee module should be locked using the uncached context. This prevents fees from being partially distributed for a given packetID. + +### Receiving side + +`OnRecvPacket` should remain unaffected by the fee module becoming locked since escrow accounts only affect the sending side. + +## Consequences + +### Positive + +The fee module can be elegantly disabled in the presence of severe bugs. + +### Negative + +Extra logic is added to account for edge cases which are only possible in the presence of bugs. + +### Neutral + +## References + +Issues: + +- [#821](https://github.com/cosmos/ibc-go/issues/821) +- [#860](https://github.com/cosmos/ibc-go/issues/860) + +PR's: + +- [#1031](https://github.com/cosmos/ibc-go/pull/1031) +- [#1029](https://github.com/cosmos/ibc-go/pull/1029) +- [#1056](https://github.com/cosmos/ibc-go/pull/1056) diff --git a/ibc/next/architecture/adr-005-consensus-height-events.mdx b/ibc/next/architecture/adr-005-consensus-height-events.mdx new file mode 100644 index 00000000..c07b9130 --- /dev/null +++ b/ibc/next/architecture/adr-005-consensus-height-events.mdx @@ -0,0 +1,94 @@ +--- +title: "ADR 005: UpdateClient Events ClientState Consensus Heights" +--- + +## Changelog + +- 25-04-2022: initial draft + +## Status + +Accepted + +## Context + +The `ibc-go` implementation leverages the [Cosmos-SDK's EventManager](https://github.com/cosmos/cosmos-sdk/blob/v0.45.4/docs/core/events.md#EventManager) to provide subscribers a method of reacting to application specific events. +Some IBC relayers depend on the [`consensus_height`](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/core/02-client/keeper/events.go#L33) attribute emitted as part of `UpdateClient` events in order to run `07-tendermint` misbehaviour detection by cross-checking the details of the *Header* emitted at a given consensus height against those of the *Header* from the originating chain. This includes such details as: + +- The `SignedHeader` containing the commitment root. +- The `ValidatorSet` that signed the *Header*. +- The `TrustedHeight` seen by the client at less than or equal to the height of *Header*. +- The last `TrustedValidatorSet` at the trusted height. + +Following the refactor of the `02-client` submodule and associated `ClientState` interfaces, it will now be possible for +light client implementations to perform such actions as batch updates, inserting `N` number of `ConsensusState`s into the application state tree with a single `UpdateClient` message. This flexibility is provided in `ibc-go` by the usage of the [Protobuf `Any`](https://developers.google.com/protocol-buffers/docs/proto3#any) field contained within the [`UpdateClient`](https://github.com/cosmos/ibc-go/blob/v3.0.0/proto/ibc/core/client/v1/tx.proto#L44) message. +For example, a batched client update message serialized as a Protobuf `Any` type for the `07-tendermint` lightclient implementation could be defined as follows: + +```protobuf +message BatchedHeaders { + repeated Header headers = 1; +} +``` + +To complement this flexibility, the `UpdateClient` handler will now support the submission of [client misbehaviour](https://github.com/cosmos/ibc/tree/master/spec/core/ics-002-client-semantics#misbehaviour) by consolidating the `Header` and `Misbehaviour` interfaces into a single `ClientMessage` interface type: + +```go +// ClientMessage is an interface used to update an IBC client. +// The update may be done by a single header, a batch of headers, misbehaviour, or any type which when verified produces +// a change to state of the IBC client +type ClientMessage interface { + proto.Message + + ClientType() string + ValidateBasic() error +} +``` + +To support this functionality the `GetHeight()` method has been omitted from the new `ClientMessage` interface. +Emission of standardised events from the `02-client` submodule now becomes problematic and is two-fold: + +1. The `02-client` submodule previously depended upon the `GetHeight()` method of `Header` types in order to [retrieve the updated consensus height](https://github.com/cosmos/ibc-go/blob/v3.0.0/modules/core/02-client/keeper/client.go#L90). +2. Emitting a single `consensus_height` event attribute is not sufficient in the case of a batched client update containing multiple *Headers*. + +## Decision + +The following decisions have been made in order to provide flexibility to consumers of `UpdateClient` events in a non-breaking fashion: + +1. Return a list of updated consensus heights `[]exported.Height` from the new `UpdateState` method of the `ClientState` interface. + +```go +// UpdateState updates and stores as necessary any associated information for an IBC client, such as the ClientState and corresponding ConsensusState. +// Upon successful update, a list of consensus heights is returned. It assumes the ClientMessage has already been verified. +UpdateState(sdk.Context, codec.BinaryCodec, sdk.KVStore, ClientMessage) []Height +``` + +2. Maintain the `consensus_height` event attribute emitted from the `02-client` update handler, but mark as deprecated for future removal. For example, with tendermint lightclients this will simply be `consensusHeights[0]` following a successful update using a single *Header*. + +3. Add an additional `consensus_heights` event attribute, containing a comma separated list of updated heights. This provides flexibility for emitting a single consensus height or multiple consensus heights in the example use-case of batched header updates. + +## Consequences + +### Positive + +- Subscribers of IBC core events can act upon `UpdateClient` events containing one or more consensus heights. +- Deprecation of the existing `consensus_height` attribute allows consumers to continue to process `UpdateClient` events as normal, with a path to upgrade to using the `consensus_heights` attribute moving forward. + +### Negative + +- Consumers of IBC core `UpdateClient` events are forced to make future code changes. + +### Neutral + +## References + +Discussions: + +- [#1208](https://github.com/cosmos/ibc-go/pull/1208#discussion_r839691927) + +Issues: + +- [#594](https://github.com/cosmos/ibc-go/issues/594) + +PRs: + +- [#1285](https://github.com/cosmos/ibc-go/pull/1285) diff --git a/ibc/next/architecture/adr-006-02-client-refactor.mdx b/ibc/next/architecture/adr-006-02-client-refactor.mdx new file mode 100644 index 00000000..f165331c --- /dev/null +++ b/ibc/next/architecture/adr-006-02-client-refactor.mdx @@ -0,0 +1,205 @@ +--- +title: "ADR 006: 02-Client Refactor" +--- + +## Changelog + +- 01-08-2022: Initial Draft + +## Status + +Accepted and applied in v7 of ibc-go + +## Context + +During the initial development of the 02-client submodule, each light client supported (06-solomachine, 07-tendermint, 09-localhost) was referenced through hardcoding. +Here is an example of the [code](https://github.com/cosmos/cosmos-sdk/commit/b93300288e3a04faef9c0774b75c13b24450ba1c#diff-c5f6b956947375f28d611f18d0e670cf28f8f305300a89c5a9b239b0eeec5064R83) that existed in the 02-client submodule: + +```go +func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.Header) (exported.ClientState, error) { + ... + + switch clientType { + case exported.Tendermint: + clientState, consensusState, err = tendermint.CheckValidityAndUpdateState( + clientState, header, ctx.BlockTime(), + ) + case exported.Localhost: + // override client state and update the block height + clientState = localhosttypes.NewClientState( + ctx.ChainID(), // use the chain ID from context since the client is from the running chain (i.e self). + ctx.BlockHeight(), + ) + default: + err = types.ErrInvalidClientType + } +``` + +To add additional light clients, code would need to be added directly to the 02-client submodule. +Evidently, this would likely become problematic as IBC scaled to many chains using consensus mechanisms beyond the initial supported light clients. +Issue [#6064](https://github.com/cosmos/cosmos-sdk/issues/6064) on the SDK addressed this problem by creating a more modular 02-client submodule. +The 02-client submodule would now interact with each light client via an interface. +While, this change was positive in development, increasing the flexibility and adoptability of IBC, it also opened the door to new problems. + +The difficulty of generalizing light clients became apparent once changes to those light clients were required. +Each light client represents a different consensus algorithm which may contain a host of complexity and nuances. +Here are some examples of issues which arose for light clients that are not applicable to all the light clients supported (06-solomachine, 07-tendermint, 09-localhost): + +### Tendermint non-zero height upgrades + +Before the launch of IBC, it was determined that the golang implementation of [tendermint](https://github.com/tendermint/tendermint) would not be capable of supporting non-zero height upgrades. +This implies that any upgrade would require changing of the chain ID and resetting the height to 0. +A chain is uniquely identified by its chain-id and validator set. +Two different chain ID's can be viewed as different chains and thus a normal update produced by a validator set cannot change the chain ID. +To work around the lack of support for non-zero height upgrades, an abstract height type was created along with an upgrade mechanism. +This type would indicate the revision number (the number of times the chain ID has been changed) and revision height (the current height of the blockchain). + +Refs: + +- Issue [#439](https://github.com/cosmos/ibc/issues/439) on IBC specification repository. +- Specification changes in [#447](https://github.com/cosmos/ibc/pull/447) +- Implementation changes for the abstract height type, [SDK#7211](https://github.com/cosmos/cosmos-sdk/pull/7211) + +### Tendermint requires misbehaviour detection during updates + +The initial release of the IBC module and the 07-tendermint light client implementation did not support misbehaviour detection during update nor did it prevent overwriting of previous updates. +Despite the fact that we designed the `ClientState` interface and developed the 07-tendermint client, we failed to detect even a duplicate update that constituted misbehaviour and thus should freeze the client. +This was fixed in PR [#141](https://github.com/cosmos/ibc-go/pull/141) which required light client implementations to be aware that they must handle duplicate updates and misbehaviour detection. +Misbehaviour detection during updates is not applicable to the solomachine nor localhost. +It is also not obvious that `CheckHeaderAndUpdateState` should be performing this functionality. + +### Localhost requires access to the entire client store + +The localhost has been broken since the initial version of the IBC module. +The localhost tried to be developed underneath the 02-client interfaces without special exception, but this proved to be impossible. +The issues were outlined in [#27](https://github.com/cosmos/ibc-go/issues/27) and further discussed in the attempted ADR in [#75](https://github.com/cosmos/ibc-go/pull/75). +Unlike all other clients, the localhost requires access to the entire IBC store and not just the prefixed client store. + +### Solomachine doesn't set consensus states + +The 06-solomachine does not set the consensus states within the prefixed client store. +It has a single consensus state that is stored within the client state. +This causes setting of the consensus state at the 02-client level to use unnecessary storage. +It also causes timeouts to fail with solo machines. +Previously, the timeout logic within IBC would obtain the consensus state at the height a timeout is being proved. +This is problematic for the solo machine as no consensus state is set. +See issue [#562](https://github.com/cosmos/ibc/issues/562) on the IBC specification repo. + +### New clients may want to do batch updates + +New light clients may not function in a similar fashion to 06-solomachine and 07-tendermint. +They may require setting many consensus states in a single update. +As @seunlanlege [states](https://github.com/cosmos/ibc-go/issues/284#issuecomment-1005583679): + +> I'm in support of these changes for 2 reasons: +> +> - This would allow light clients to handle batch header updates in CheckHeaderAndUpdateState, for the special case of 11-beefy proving the finality for a batch of headers is much more space and time efficient than the space/time complexity of proving each individual headers in that batch, combined. +> +> - This also allows for a single light client instance of 11-beefy be used to prove finality for every parachain connected to the relay chain (Polkadot/Kusama). We achieve this by setting the appropriate ConsensusState for individual parachain headers in CheckHeaderAndUpdateState + +## Decision + +### Require light clients to set client and consensus states + +The IBC specification states: + +> If the provided header was valid, the client MUST also mutate internal state to store now-finalised consensus roots and update any necessary signature authority tracking (e.g. changes to the validator set) for future calls to the validity predicate. + +The initial version of the IBC go SDK based module did not fulfill this requirement. +Instead, the 02-client submodule required each light client to return the client and consensus state which should be updated in the client prefixed store. +This decision lead to the issues "Solomachine doesn't set consensus states" and "New clients may want to do batch updates". + +Each light client should be required to set its own client and consensus states on any update necessary. +The go implementation should be changed to match the specification requirements. +This will allow more flexibility for light clients to manage their own internal storage and do batch updates. + +### Merge `Header`/`Misbehaviour` interface and rename to `ClientMessage` + +Remove `GetHeight()` from the header interface (as light clients now set the client/consensus states). +This results in the `Header`/`Misbehaviour` interfaces being the same. +To reduce complexity of the codebase, the `Header`/`Misbehaviour` interfaces should be merged into `ClientMessage`. +`ClientMessage` will provide the client with some authenticated information which may result in regular updates, misbehaviour detection, batch updates, or other custom functionality a light client requires. + +### Split `CheckHeaderAndUpdateState` into 4 functions + +See [#668](https://github.com/cosmos/ibc-go/issues/668). + +Split `CheckHeaderAndUpdateState` into 4 functions: + +- `VerifyClientMessage` +- `CheckForMisbehaviour` +- `UpdateStateOnMisbehaviour` +- `UpdateState` + +`VerifyClientMessage` checks the that the structure of a `ClientMessage` is correct and that all authentication data provided is valid. + +`CheckForMisbehaviour` checks to see if a `ClientMessage` is evidence of misbehaviour. + +`UpdateStateOnMisbehaviour` freezes the client and updates its state accordingly. + +`UpdateState` performs a regular update or a no-op on duplicate updates. + +The code roughly looks like: + +```go +func (k Keeper) UpdateClient(ctx sdk.Context, clientID string, header exported.Header) error { + ... + + if err := clientState.VerifyClientMessage(clientMessage); err != nil { + return err + } + + foundMisbehaviour := clientState.CheckForMisbehaviour(clientMessage) + if foundMisbehaviour { + clientState.UpdateStateOnMisbehaviour(header) + // emit misbehaviour event + return + } + + clientState.UpdateState(clientMessage) // expects no-op on duplicate header + // emit update event + return +} +``` + +### Add `GetTimestampAtHeight` to the client state interface + +By adding `GetTimestampAtHeight` to the ClientState interface, we allow light clients which do non-traditional consensus state/timestamp storage to process timeouts correctly. +This fixes the issues outlined for the solo machine client. + +### Add generic verification functions + +As the complexity and the functionality grows, new verification functions will be required for additional paths. +This was explained in [#684](https://github.com/cosmos/ibc/issues/684) on the specification repo. +These generic verification functions would be immediately useful for the new paths added in connection/channel upgradability as well as for custom paths defined by IBC applications such as Interchain Queries. +The old verification functions (`VerifyClientState`, `VerifyConnection`, etc) should be removed in favor of the generic verification functions. + +## Consequences + +### Positive + +- Flexibility for light client implementations +- Well defined interfaces and their required functionality +- Generic verification functions +- Applies changes necessary for future client/connection/channel upgrabability features +- Timeout processing for solo machines +- Reduced code complexity + +### Negative + +- The refactor touches on sensitive areas of the ibc-go codebase +- Changing of established naming (`Header`/`Misbehaviour` to `ClientMessage`) + +### Neutral + +No notable consequences + +## References + +Issues: + +- [#284](https://github.com/cosmos/ibc-go/issues/284) + +PRs: + +- [#1871](https://github.com/cosmos/ibc-go/pull/1871) diff --git a/ibc/next/architecture/adr-007-solomachine-signbytes.mdx b/ibc/next/architecture/adr-007-solomachine-signbytes.mdx new file mode 100644 index 00000000..e1872e24 --- /dev/null +++ b/ibc/next/architecture/adr-007-solomachine-signbytes.mdx @@ -0,0 +1,54 @@ +--- +title: "ADR 007: Solo Machine Sign Bytes" +--- + +## Changelog + +- 02-08-2022: Initial draft + +## Status + +Accepted, applied in v7 + +## Context + +The `06-solomachine` implementation up until ibc-go v7 constructed sign bytes using a `DataType` which described what type of data was being signed. +This design decision arose from a misunderstanding of the security implications. +It was noted that the proto definitions do not [provide uniqueness](https://github.com/cosmos/cosmos-sdk/pull/7237#discussion_r484264573) which is a necessity for ensuring two signatures over different data types can never be the same. +What was missed is that the uniqueness is not provided by the proto definition, but by the usage of the proto definition. +The path provided by core IBC will be unique and is already encoded into the signature data. +Thus two different paths with the same data values will encode differently which provides signature uniqueness. + +Furthermore, the current construction does not support the proposed changes in the spec repo to support [Generic Verification functions](https://github.com/cosmos/ibc/issues/684). +This is because in order to verify a new path, a new `DataType` must be added for that path. + +## Decision + +Remove `DataType` and change the `DataType` in the `SignBytes` and `SignatureAndData` to be `Path`. +The new `Path` field should be bytes. +Remove all `...Data` proto definitions except for `HeaderData` +These `...Data` definitions were created previously for each `DataType`. +The proto version of the solo machine proto definitions should be bumped to `v3`. + +This removes an extra layer of complexity from signature construction and allows for support of generic verification. + +## Consequences + +### Positive + +- Simplification of solo machine signature construction +- Support for generic verification + +### Negative + +- Breaks existing signature construction in a non-backwards compatible way +- Solo machines must update to handle the new format +- Migration required for solo machine client and consensus states + +### Neutral + +No notable consequences + +## References + +- [#1141](https://github.com/cosmos/ibc-go/issues/1141) diff --git a/ibc/next/architecture/adr-008-app-caller-cbs.mdx b/ibc/next/architecture/adr-008-app-caller-cbs.mdx new file mode 100644 index 00000000..f75967b3 --- /dev/null +++ b/ibc/next/architecture/adr-008-app-caller-cbs.mdx @@ -0,0 +1,571 @@ +--- +title: "ADR 008: Callback to IBC Actors" +--- + +## Changelog + +- 10-08-2022: Initial Draft +- 22-03-2023: Merged +- 13-09-2023: Updated with decisions made in implementation +- 24-02-2025: RecvPacket callback error now returns error acknowledgement + +## Status + +Accepted, middleware implemented + +## Context + +IBC was designed with callbacks between core IBC and IBC applications. IBC apps would send a packet to core IBC. When the result of the packet lifecycle eventually resolved into either an acknowledgement or a timeout, core IBC called a callback on the IBC application so that the IBC application could take action on the basis of the result (e.g. unescrow tokens for ICS-20). + +This setup worked well for off-chain users interacting with IBC applications. + +We are now seeing the desire for secondary applications (e.g. smart contracts, modules) to call into IBC apps as part of their state machine logic and then do some actions on the basis of the packet result. Or to receive a packet from IBC and do some logic upon receipt. + +Example Usecases: + +- Send an ICS-20 packet, and if it is successful, then send an ICA-packet to swap tokens on LP and return funds to sender +- Execute some logic upon receipt of token transfer to a smart contract address + +This requires a second layer of callbacks. The IBC application already gets the result of the packet from core IBC, but currently there is no standardized way to pass this information on to an actor module/smart contract. + +## Definitions + +- Actor: an actor is an on-chain module (this may be a hardcoded module in the chain binary or a smart contract) that wishes to execute custom logic whenever IBC receives a packet flow that it has either sent or received. It **must** be addressable by a string value. + +## Decision + +Create a middleware that can interface between IBC applications and smart contract VMs. The IBC applications and smart contract VMs will implement respective interfaces that will then be composed together by the callback middleware to allow a smart contract of any compatible VM to interact programmatically with an IBC application. + +## Data structures + +The `CallbackPacketData` struct will get constructed from custom callback data in the application packet. The `CallbackAddress` is the IBC Actor address on which the callback should be called on. The `SenderAddress` is also provided to optionally allow a VM to ensure that the sender is the same as the callback address. + +The struct also defines a `CommitGasLimit` which is the maximum gas a callback is allowed to use. If the callback exceeds this limit, the callback will panic and the tx will commit without the callback's state changes. + +The `ExecutionGasLimit` is the practical limit of the tx execution that is set in the context gas meter. It is the minimum of the `CommitGasLimit` and the gas left in the context gas meter which is determined by the relayer's choice of tx gas limit. If `ExecutionGasLimit < CommitGasLimit`, then an out-of-gas error will revert the entire transaction without committing anything, allowing for a different relayer to retry with a larger tx gas limit. + +Any middleware targeting this interface for callback handling should define a global limit that caps the gas that a callback is allowed to take (especially on AcknowledgePacket and TimeoutPacket) so that a custom callback does not prevent the packet lifecycle from completing. However, since this is a global cap it is likely to be very large. Thus, users may specify a smaller limit to cap the amount of fees a relayer must pay in order to complete the packet lifecycle on the user's behalf. + +```go +// Implemented by any packet data type that wants to support PacketActor callbacks +// PacketActor's will be unable to act on any packet data type that does not implement +// this interface. +type CallbackPacketData struct { + CallbackAddress: string + ExecutionGasLimit: uint64 + SenderAddress: string + CommitGasLimit: uint64 +} +``` + +IBC Apps or middleware can then call the IBCActor callbacks like so in their own callbacks: + +### Callback Middleware + +The CallbackMiddleware wraps an underlying IBC application along with a contractKeeper that delegates the callback to a virtual machine. This allows the Callback middleware to interface any compatible IBC application with any compatible VM (e.g. EVM, WASM) so long as the application implements the `CallbacksCompatibleModule` interface and the VM implements the `ContractKeeper` interface. + +```go +// IBCMiddleware implements the ICS26 callbacks for the ibc-callbacks middleware given +// the underlying application. +type IBCMiddleware struct { + app types.CallbacksCompatibleModule + ics4Wrapper porttypes.ICS4Wrapper + + contractKeeper types.ContractKeeper + + // maxCallbackGas defines the maximum amount of gas that a callback actor can ask the + // relayer to pay for. If a callback fails due to insufficient gas, the entire tx + // is reverted if the relayer hadn't provided the minimum(userDefinedGas, maxCallbackGas). + // If the actor hasn't defined a gas limit, then it is assumed to be the maxCallbackGas. + maxCallbackGas uint64 +} +``` + +### Callback-Compatible IBC Application + +The `CallbacksCompatibleModule` extends `porttypes.IBCModule` to include an `UnmarshalPacketData` function that allows the middleware to request that the underlying app unmarshal the packet data. This will then allow the middleware to retrieve the callback specific data from an arbitrary set of IBC application packets. + +```go +// CallbacksCompatibleModule is an interface that combines the IBCModule and PacketDataUnmarshaler +// interfaces to assert that the underlying application supports both. +type CallbacksCompatibleModule interface { + porttypes.IBCModule + porttypes.PacketDataUnmarshaler +} + +// PacketDataUnmarshaler defines an optional interface which allows a middleware to +// request the packet data to be unmarshaled by the base application. +type PacketDataUnmarshaler interface { + // UnmarshalPacketData unmarshals the packet data into a concrete type + // ctx, portID, channelID are provided as arguments, so that (if needed) + // the packet data can be unmarshaled based on the channel version. + // the version of the underlying app is also returned. + UnmarshalPacketData(ctx sdk.Context, portID, channelID string, bz []byte) (interface{}, string, error) +} +``` + +The application's packet data must additionally implement the following interfaces: + +```go +// PacketData defines an optional interface which an application's packet data structure may implement. +type PacketData interface { + // GetPacketSender returns the sender address of the packet data. + // If the packet sender is unknown or undefined, an empty string should be returned. + GetPacketSender(sourcePortID string) string +} + +// PacketDataProvider defines an optional interfaces for retrieving custom packet data stored on behalf of another application. +// An existing problem in the IBC middleware design is the inability for a middleware to define its own packet data type and insert packet sender provided information. +// A short term solution was introduced into several application's packet data to utilize a memo field to carry this information on behalf of another application. +// This interfaces standardizes that behaviour. Upon realization of the ability for middleware's to define their own packet data types, this interface will be deprecated and removed with time. +type PacketDataProvider interface { + // GetCustomPacketData returns the packet data held on behalf of another application. + // The name the information is stored under should be provided as the key. + // If no custom packet data exists for the key, nil should be returned. + GetCustomPacketData(key string) interface{} +} +``` + +The callback data can be embedded in an application packet by providing custom packet data for source and destination callback in the custom packet data under the appropriate key. + +```jsonc +// Custom Packet data embedded as a JSON object in the packet data + +// src callback custom data +{ + "src_callback": { + "address": "callbackAddressString", + // optional + "gas_limit": "userDefinedGasLimitString", + } +} + +// dest callback custom data +{ + "dest_callback": { + "address": "callbackAddressString", + // optional + "gas_limit": "userDefinedGasLimitString", + } +} + +// src and dest callback custom data embedded together +{ + "src_callback": { + "address": "callbackAddressString", + // optional + "gas_limit": "userDefinedGasLimitString", + }, + "dest_callback": { + "address": "callbackAddressString", + // optional + "gas_limit": "userDefinedGasLimitString", + } +} +``` + +## ContractKeeper + +The `ContractKeeper` interface must be implemented by any VM that wants to support IBC callbacks. This allows for separation of concerns +between the middleware which is handling logic intended for all VMs (e.g. setting gas meter, extracting callback data, emitting events), +while the ContractKeeper can handle the specific details of calling into the VM in question. + +The `ContractKeeper` **may** impose additional checks such as ensuring that the contract address is the same as the packet sender in source callbacks. +It may also disable certain callback methods by simply performing a no-op. + +```go +// ContractKeeper defines the entry points exposed to the VM module which invokes a smart contract +type ContractKeeper interface { + // IBCSendPacketCallback is called in the source chain when a PacketSend is executed. The + // packetSenderAddress is determined by the underlying module, and may be empty if the sender is + // unknown or undefined. The contract is expected to handle the callback within the user defined + // gas limit, and handle any errors, or panics gracefully. + // This entry point is called with a cached context. If an error is returned, then the changes in + // this context will not be persisted, and the error will be propagated to the underlying IBC + // application, resulting in a packet send failure. + // + // Implementations are provided with the packetSenderAddress and MAY choose to use this to perform + // validation on the origin of a given packet. It is recommended to perform the same validation + // on all source chain callbacks (SendPacket, AcknowledgementPacket, TimeoutPacket). This + // defensively guards against exploits due to incorrectly wired SendPacket ordering in IBC stacks. + // + // The version provided is the base application version for the given packet send. This allows + // contracts to determine how to unmarshal the packetData. + IBCSendPacketCallback( + cachedCtx sdk.Context, + sourcePort string, + sourceChannel string, + timeoutHeight clienttypes.Height, + timeoutTimestamp uint64, + packetData []byte, + contractAddress, + packetSenderAddress string, + version string, + ) error + // IBCOnAcknowledgementPacketCallback is called in the source chain when a packet acknowledgement + // is received. The packetSenderAddress is determined by the underlying module, and may be empty if + // the sender is unknown or undefined. The contract is expected to handle the callback within the + // user defined gas limit, and handle any errors, or panics gracefully. + // This entry point is called with a cached context. If an error is returned, then the changes in + // this context will not be persisted, but the packet lifecycle will not be blocked. + // + // Implementations are provided with the packetSenderAddress and MAY choose to use this to perform + // validation on the origin of a given packet. It is recommended to perform the same validation + // on all source chain callbacks (SendPacket, AcknowledgementPacket, TimeoutPacket). This + // defensively guards against exploits due to incorrectly wired SendPacket ordering in IBC stacks. + // + // The version provided is the base application version for the given packet send. This allows + // contracts to determine how to unmarshal the packetData. + IBCOnAcknowledgementPacketCallback( + cachedCtx sdk.Context, + packet channeltypes.Packet, + acknowledgement []byte, + relayer sdk.AccAddress, + contractAddress, + packetSenderAddress string, + version string, + ) error + // IBCOnTimeoutPacketCallback is called in the source chain when a packet is not received before + // the timeout height. The packetSenderAddress is determined by the underlying module, and may be + // empty if the sender is unknown or undefined. The contract is expected to handle the callback + // within the user defined gas limit, and handle any error, out of gas, or panics gracefully. + // This entry point is called with a cached context. If an error is returned, then the changes in + // this context will not be persisted, but the packet lifecycle will not be blocked. + // + // Implementations are provided with the packetSenderAddress and MAY choose to use this to perform + // validation on the origin of a given packet. It is recommended to perform the same validation + // on all source chain callbacks (SendPacket, AcknowledgementPacket, TimeoutPacket). This + // defensively guards against exploits due to incorrectly wired SendPacket ordering in IBC stacks. + // + // The version provided is the base application version for the given packet send. This allows + // contracts to determine how to unmarshal the packetData. + IBCOnTimeoutPacketCallback( + cachedCtx sdk.Context, + packet channeltypes.Packet, + relayer sdk.AccAddress, + contractAddress, + packetSenderAddress string, + version string, + ) error + // IBCReceivePacketCallback is called in the destination chain when a packet acknowledgement is written. + // The contract is expected to handle the callback within the user defined gas limit. + // This entry point is called with a cached context. If an error is returned, then the error + // will be written as an error acknowledgement. This will cause the context changes made by the contract + // to be reverted along with any state changes made by the underlying application. + // The error acknowledgement will then be relayed to the sending application which can perform + // its error acknowledgement logic (e.g. refunding tokens back to user) + // + // The version provided is the base application version for the given packet send. This allows + // contracts to determine how to unmarshal the packetData. + IBCReceivePacketCallback( + cachedCtx sdk.Context, + packet ibcexported.PacketI, + ack ibcexported.Acknowledgement, + contractAddress string, + version string, + ) error +} +``` + +### PacketCallbacks + +The packet callbacks implemented in the middleware will first call the underlying application and then route to the IBC actor callback in the post-processing step. +It will extract the callback data from the application packet and set the callback gas meter depending on the global limit, the user limit, and the gas left in the transaction gas meter. +The callback will then be routed through the callback keeper which will either panic or return a result (success or failure). In the event of a (non-oog) panic or an error, the callback state changes +are discarded and the transaction is committed. + +If the relayer-defined gas limit is exceeded before the user-defined gas limit or global callback gas limit is exceeded, then the entire transaction is reverted to allow for resubmission. If the chain-defined or user-defined gas limit is reached, +the callback state changes are reverted and the transaction is committed. + +For the `SendPacket` callback, we will revert the entire transaction on any kind of error or panic. This is because the packet lifecycle has not yet started, so we can revert completely to avoid starting the packet lifecycle if the callback is not successful. + +```go +// SendPacket implements source callbacks for sending packets. +// It defers to the underlying application and then calls the contract callback. +// If the contract callback returns an error, panics, or runs out of gas, then +// the packet send is rejected. +func (im IBCMiddleware) SendPacket( + ctx sdk.Context, + chanCap *capabilitytypes.Capability, + sourcePort string, + sourceChannel string, + timeoutHeight clienttypes.Height, + timeoutTimestamp uint64, + data []byte, +) (uint64, error) { + // run underlying app logic first + // IBCActor logic will postprocess + seq, err := im.ics4Wrapper.SendPacket(ctx, chanCap, sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, data) + if err != nil { + return 0, err + } + + // use underlying app to get source callback information from packet data + callbackData, err := types.GetSourceCallbackData(im.app, data, sourcePort, ctx.GasMeter().GasRemaining(), im.maxCallbackGas) + // SendPacket is not blocked if the packet does not opt-in to callbacks + if err != nil { + return seq, nil + } + + callbackExecutor := func(cachedCtx sdk.Context) error { + return im.contractKeeper.IBCSendPacketCallback( + cachedCtx, sourcePort, sourceChannel, timeoutHeight, timeoutTimestamp, data, callbackData.CallbackAddress, callbackData.SenderAddress, + ) + } + + err = im.processCallback(ctx, types.CallbackTypeSendPacket, callbackData, callbackExecutor) + // contract keeper is allowed to reject the packet send. + if err != nil { + return 0, err + } + + types.EmitCallbackEvent(ctx, sourcePort, sourceChannel, seq, types.CallbackTypeSendPacket, callbackData, nil) + return seq, nil +} + +// WriteAcknowledgement implements the ReceivePacket destination callbacks for the ibc-callbacks middleware +// during asynchronous packet acknowledgement. +// It defers to the underlying application and then calls the contract callback. +// If the contract callback runs out of gas and may be retried with a higher gas limit then the state changes are +// reverted via a panic. +func (im IBCMiddleware) WriteAcknowledgement( + ctx sdk.Context, + chanCap *capabilitytypes.Capability, + packet ibcexported.PacketI, + ack ibcexported.Acknowledgement, +) error { + // run underlying app logic first + // IBCActor logic will postprocess + err := im.ics4Wrapper.WriteAcknowledgement(ctx, chanCap, packet, ack) + if err != nil { + return err + } + + // use underlying app to get destination callback information from packet data + callbackData, err := types.GetDestCallbackData( + im.app, packet.GetData(), packet.GetSourcePort(), ctx.GasMeter().GasRemaining(), im.maxCallbackGas, + ) + // WriteAcknowledgement is not blocked if the packet does not opt-in to callbacks + if err != nil { + return nil + } + + callbackExecutor := func(cachedCtx sdk.Context) error { + return im.contractKeeper.IBCReceivePacketCallback(cachedCtx, packet, ack, callbackData.CallbackAddress) + } + + // callback execution errors are not allowed to block the packet lifecycle, they are only used in event emissions + err = im.processCallback(ctx, types.CallbackTypeReceivePacket, callbackData, callbackExecutor) + // emit events + types.EmitCallbackEvent( + ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), + types.CallbackTypeAcknowledgementPacket, callbackData, err, + ) + + return nil +} + +// Call the IBCActor recvPacket callback after processing the packet +// if the recvPacket callback exists. If the callback returns an error +// then return an error ack to revert all packet data processing. +func (im IBCMiddleware) OnRecvPacket( + ctx sdk.Context, + packet channeltypes.Packet, + relayer sdk.AccAddress, +) (ack exported.Acknowledgement) { + // run underlying app logic first + // IBCActor logic will postprocess + ack := im.app.OnRecvPacket(ctx, packet, relayer) + // if ack is nil (asynchronous acknowledgements), then the callback will be handled in WriteAcknowledgement + // if ack is not successful, all state changes are reverted. If a packet cannot be received, then there is + // no need to execute a callback on the receiving chain. + if ack == nil || !ack.Success() { + return ack + } + + // use underlying app to get destination callback information from packet data + callbackData, err := types.GetDestCallbackData( + im.app, packet.GetData(), packet.GetSourcePort(), ctx.GasMeter().GasRemaining(), im.maxCallbackGas, + ) + // OnRecvPacket is not blocked if the packet does not opt-in to callbacks + if err != nil { + return ack + } + + callbackExecutor := func(cachedCtx sdk.Context) error { + return im.contractKeeper.IBCReceivePacketCallback(cachedCtx, packet, ack, callbackData.CallbackAddress) + } + + // callback execution errors are not allowed to block the packet lifecycle, they are only used in event emissions + err = im.processCallback(ctx, types.CallbackTypeReceivePacket, callbackData, callbackExecutor) + types.EmitCallbackEvent( + ctx, packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence(), + types.CallbackTypeReceivePacket, callbackData, err, + ) + if err != nil { + return channeltypes.NewErrorAcknowledgement(err) + } + + return ack +} + +// Call the IBCActor acknowledgementPacket callback after processing the packet +// if the ackPacket callback exists and returns an error +// DO NOT return the error upstream. The acknowledgement must complete for the packet +// lifecycle to end, so the custom callback cannot block completion. +// Instead we emit error events and set the error in state +// so that users and on-chain logic can handle this appropriately +func (im IBCModule) OnAcknowledgementPacket( + ctx sdk.Context, + packet channeltypes.Packet, + acknowledgement []byte, + relayer sdk.AccAddress, +) error { + // we first call the underlying app to handle the acknowledgement + // IBCActor logic will postprocess + err := im.app.OnAcknowledgementPacket(ctx, packet, acknowledgement, relayer) + if err != nil { + return err + } + + // use underlying app to get source callback information from packet data + callbackData, err := types.GetSourceCallbackData( + im.app, packet.GetData(), packet.GetSourcePort(), ctx.GasMeter().GasRemaining(), im.maxCallbackGas, + ) + // OnAcknowledgementPacket is not blocked if the packet does not opt-in to callbacks + if err != nil { + return nil + } + + callbackExecutor := func(cachedCtx sdk.Context) error { + return im.contractKeeper.IBCOnAcknowledgementPacketCallback( + cachedCtx, packet, acknowledgement, relayer, callbackData.CallbackAddress, callbackData.SenderAddress, + ) + } + + // callback execution errors are not allowed to block the packet lifecycle, they are only used in event emissions + err = im.processCallback(ctx, types.CallbackTypeAcknowledgementPacket, callbackData, callbackExecutor) + types.EmitCallbackEvent( + ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), + types.CallbackTypeAcknowledgementPacket, callbackData, err, + ) + + return nil +} + +// Call the IBCActor timeoutPacket callback after processing the packet +// if the timeoutPacket callback exists and returns an error +// DO NOT return the error upstream. The timeout must complete for the packet +// lifecycle to end, so the custom callback cannot block completion. +// Instead we emit error events and set the error in state +// so that users and on-chain logic can handle this appropriately +func (im IBCModule) OnTimeoutPacket( + ctx sdk.Context, + packet channeltypes.Packet, + relayer sdk.AccAddress, +) error { + // application-specific onTimeoutPacket logic + err := im.app.OnTimeoutPacket(ctx, packet, relayer) + if err != nil { + return err + } + + // use underlying app to get source callback information from packet data + callbackData, err := types.GetSourceCallbackData( + im.app, packet.GetData(), packet.GetSourcePort(), ctx.GasMeter().GasRemaining(), im.maxCallbackGas, + ) + // OnTimeoutPacket is not blocked if the packet does not opt-in to callbacks + if err != nil { + return nil + } + + callbackExecutor := func(cachedCtx sdk.Context) error { + return im.contractKeeper.IBCOnTimeoutPacketCallback(cachedCtx, packet, relayer, callbackData.CallbackAddress, callbackData.SenderAddress) + } + + // callback execution errors are not allowed to block the packet lifecycle, they are only used in event emissions + err = im.processCallback(ctx, types.CallbackTypeTimeoutPacket, callbackData, callbackExecutor) + types.EmitCallbackEvent( + ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence(), + types.CallbackTypeTimeoutPacket, callbackData, err, + ) + + return nil +} + +// processCallback executes the callbackExecutor and reverts contract changes if the callbackExecutor fails. +// +// Error Precedence and Returns: +// - oogErr: Takes the highest precedence. If the callback runs out of gas, an error wrapped with types.ErrCallbackOutOfGas is returned. +// - panicErr: Takes the second-highest precedence. If a panic occurs and it is not propagated, an error wrapped with types.ErrCallbackPanic is returned. +// - callbackErr: If the callbackExecutor returns an error, it is returned as-is. +// +// panics if +// - the contractExecutor panics for any reason, and the callbackType is SendPacket, or +// - the contractExecutor runs out of gas and the relayer has not reserved gas grater than or equal to +// CommitGasLimit. +func (IBCMiddleware) processCallback( + ctx sdk.Context, callbackType types.CallbackType, + callbackData types.CallbackData, callbackExecutor func(sdk.Context) error, +) (err error) { + cachedCtx, writeFn := ctx.CacheContext() + cachedCtx = cachedCtx.WithGasMeter(storetypes.NewGasMeter(callbackData.ExecutionGasLimit)) + + defer func() { + // consume the minimum of g.consumed and g.limit + ctx.GasMeter().ConsumeGas(cachedCtx.GasMeter().GasConsumedToLimit(), fmt.Sprintf("ibc %s callback", callbackType)) + + // recover from all panics except during SendPacket callbacks + if r := recover(); r != nil { + if callbackType == types.CallbackTypeSendPacket { + panic(r) + } + err = errorsmod.Wrapf(types.ErrCallbackPanic, "ibc %s callback panicked with: %v", callbackType, r) + } + + // if the callback ran out of gas and the relayer has not reserved enough gas, then revert the state + if cachedCtx.GasMeter().IsPastLimit() { + if callbackData.AllowRetry() { + panic(storetypes.ErrorOutOfGas{Descriptor: fmt.Sprintf("ibc %s callback out of gas; commitGasLimit: %d", callbackType, callbackData.CommitGasLimit)}) + } + err = errorsmod.Wrapf(types.ErrCallbackOutOfGas, "ibc %s callback out of gas", callbackType) + } + + // allow the transaction to be committed, continuing the packet lifecycle + }() + + err = callbackExecutor(cachedCtx) + if err == nil { + writeFn() + } + + return err +} +``` + +Chains are expected to specify a `maxCallbackGas` to ensure that callbacks do not consume an arbitrary amount of gas. Thus, it should always be possible for a relayer to complete the packet lifecycle even if the actor callbacks cannot run successfully. + +## Consequences + +### Positive + +- IBC Actors can now programmatically execute logic that involves sending a packet and then performing some additional logic once the packet lifecycle is complete +- Middleware implementing ADR-8 can be generally used for any application +- Leverages a similar callback architecture to the one used between core IBC and IBC applications + +### Negative + +- Callbacks may now have unbounded gas consumption since the actor may execute arbitrary logic. Chains implementing this feature should take care to place limitations on how much gas an actor callback can consume. +- The relayer pays for the callback gas instead of the IBCActor + +### Neutral + +- Application packets that want to support ADR-8 must additionally have their packet data implement `PacketDataProvider` and `PacketData` interfaces. +- Applications must implement `PacketDataUnmarshaler` interface +- Callback receiving module must implement the `ContractKeeper` interface + +## References + +- [Original issue](https://github.com/cosmos/ibc-go/issues/1660) +- [CallbackPacketData interface implementation](https://github.com/cosmos/ibc-go/pull/3287) +- [ICS 20, ICS 27 implementations of the CallbackPacketData interface](https://github.com/cosmos/ibc-go/pull/3287) diff --git a/ibc/next/architecture/adr-009-v6-ics27-msgserver.mdx b/ibc/next/architecture/adr-009-v6-ics27-msgserver.mdx new file mode 100644 index 00000000..e9ac0430 --- /dev/null +++ b/ibc/next/architecture/adr-009-v6-ics27-msgserver.mdx @@ -0,0 +1,117 @@ +--- +title: "ADR 009: ICS27 Message Server Addition" +--- + +## Changelog + +- 07-09-2022: Initial draft + +## Status + +Accepted, implemented in v6 of ibc-go + +## Context + +ICS 27 (Interchain Accounts) brought a cross-chain account management protocol built upon IBC. +It enabled chains to programmatically create accounts on behalf of counterparty chains which may enable a variety of authentication methods for this interchain account. +The initial release of ICS 27 focused on enabling authentication schemes that may not require signing with a private key, such as via on-chain mechanisms like governance. + +Following the initial release of ICS 27 it became evident that: + +- a default authentication module would enable more usage of ICS 27 +- generic authentication modules should be capable of authenticating an interchain account registration +- application logic which wraps ICS 27 packet sends does not need to be associated with the authentication logic + +## Decision + +The controller module should be simplified to remove the correlation between the authentication logic for an interchain account and the application logic for an interchain account. +To minimize disruption to developers working on the original design of the ICS 27 controller module, all changes will be made in a backwards compatible fashion. + +### Msg server + +To achieve this, as stated by [@damiannolan](https://github.com/cosmos/ibc-go/issues/2026#issue-1341640594), it was proposed to: + +> Add a new `MsgServer` to `27-interchain-accounts` which exposes two distinct rpc endpoints: +> +> - `RegisterInterchainAccount` +> - `SendTx` + +This will enable any SDK (authentication) module to register interchain accounts and send transactions on their behalf. +Examples of existing SDK modules which would benefit from this change include: + +- x/auth +- x/gov +- x/group + +The existing go functions: `RegisterInterchainAccount()` and `SendTx()` will remain to operate as they did in previous release versions. + +This will be possible for SDK v0.46.x and above. + +### Allow `nil` underlying applications + +Authentication modules should interact with the controller module via the message server and should not be associated with application logic. +For now, it will be allowed to set a `nil` underlying application. +A future version may remove the underlying application entirely. + +See issue [#2040](https://github.com/cosmos/ibc-go/issues/2040) + +### Channel capability claiming + +The controller module will now claim the channel capability in `OnChanOpenInit`. +Underlying applications will be passed a `nil` capability in `OnChanOpenInit`. + +Channel capability migrations will be added in two steps: + +- Upgrade handler migration which modifies the channel capability owner from the underlying app to the controller module +- ICS 27 module automatic migration which asserts the upgrade handler channel capability migration has been performed successfully + +See issue [#2033](https://github.com/cosmos/ibc-go/issues/2033) + +### Middleware enabled channels + +In order to maintain backwards compatibility and avoid requiring underlying application developers to account for interchain accounts they did not register, a boolean mapping has been added to track the behaviour of how an account was created. + +If the account was created via the legacy API, then the underlying application callbacks will be executed. + +If the account was created with the new API (message server), then the underlying application callbacks will not be executed. + +See issue [#2145](https://github.com/cosmos/ibc-go/issues/2145) + +### Future considerations + +[ADR 008](https://github.com/cosmos/ibc-go/pull/1976) proposes the creation of a middleware which enables callers of an IBC packet send to perform application logic in conjunction with the IBC application. +The underlying application can be removed at the availability of such a middleware as that will be the preferred method for executing application logic upon a ICS 27 packet send. + +### Miscellaneous + +In order to avoid import cycles, the genesis types have been moved to their own directory. +A new protobuf package has been created for the genesis types. + +See PR [#2133](https://github.com/cosmos/ibc-go/pull/2133) + +An additional field has been added to the `ActiveChannel` type to store the `IsMiddlewareEnabled` field upon genesis import/export. + +See issue [#2165](https://github.com/cosmos/ibc-go/issues/2165) + +## Consequences + +### Positive + +- default authentication modules are provided (x/auth, x/group, x/gov) +- any SDK authentication module may now be used with ICS 27 +- separation of authentication from application logic in relation to ICS 27 +- minimized disruption to existing development around ICS 27 controller module +- underlying applications no longer have to handle capabilities +- removal of the underlying application upon the creation of ADR 008 may be done in a minimally disruptive fashion +- only underlying applications which registered the interchain account will perform application logic for that account (underlying applications do not need to be aware of accounts they did not register) + +### Negative + +- the security model has been reduced to that of the SDK. SDK modules may send packets for any interchain account. +- additional maintenance of the messages added and the middleware enabled flag +- underlying applications which will become ADR 008 modules are not required to be aware of accounts they did not register +- calling legacy API vs the new API results in different behaviour for ICS 27 application stacks which have an underlying application + +### Neutral + +- A major release is required diff --git a/ibc/next/architecture/adr-010-light-clients-as-sdk-modules.mdx b/ibc/next/architecture/adr-010-light-clients-as-sdk-modules.mdx new file mode 100644 index 00000000..2bee6e88 --- /dev/null +++ b/ibc/next/architecture/adr-010-light-clients-as-sdk-modules.mdx @@ -0,0 +1,108 @@ +--- +title: "ADR 010: IBC Light Clients As SDK Modules" +--- + +## Changelog + +- 12-12-2022: initial draft + +## Status + +Proposed + +## Context + +ibc-go has 3 main consumers: + +- IBC light clients +- IBC applications +- relayers + +Relayers listen and respond to events emitted by ibc-go while IBC light clients and applications are invoked by core IBC. +Currently there exists two different approaches to callbacks being invoked by core IBC. + +IBC light clients currently are invoked by a `ClientState` and `ConsensusState` interface as defined by [core IBC](https://github.com/cosmos/ibc-go/blob/v7.0.0/modules/core/exported/client.go#L36). +The 02-client submodule will retrieve the `ClientState` or `ConsensusState` from the IBC store in order to perform callbacks to the light client. +This design requires all required information for the light client to function to be stored in the `ClientState` or `ConsensusState` or potentially under metadata keys for a specific client instance. +Additional information may be provided by core IBC via the defined interface arguments if that information is generic enough to be useful to all IBC light clients. +This constraint has proved problematic as pass through clients (such as wasm) cannot maintain easy access to a VM instance. +In addition, without increasing the size of the defined `ClientState` interface, light clients are unable to take advantage of basic built-in SDK functionality such as genesis import/export and migrations. + +The other approach used to perform callback logic is via registered SDK modules. +This approach is used by core IBC to interact with IBC applications. +IBC applications will register their callbacks on the IBC router at compile time. +When a packet comes in, core IBC will use the IBC router to lookup the registered callback functions for the provided packet. +The benefit of registered callbacks opposed to interface functions is that additional information may be accessed via external keepers. +Because the IBC applications are also SDK modules, they additionally get access to a host of functionality provided by the SDK. +This includes: genesis import/export, migrations, query/transaction CLI commands, type registration, gRPC query registration, and message server registration. + +As described in [ADR 006](./adr-006-02-client-refactor.md), generalizing light client behaviour is difficult. +IBC light clients will obtain greater flexibility and control via the registered SDK module approach. + +## Decision + +Instead of using two different approaches to invoking callbacks, IBC light clients should be invoked as SDK modules. +Over time and as necessary, core IBC should adjust its interactions with light clients such that they are SDK modules as opposed to interfaces. + +One immediate decision that has already been applied is to formalize light client type registration via the inclusion of an `AppModuleBasic` within the `ModuleManager` for a chain. +The [tendermint](https://github.com/cosmos/ibc-go/pull/2825) and [solo machine](https://github.com/cosmos/ibc-go/pull/2826) clients were refactored to include this `AppModuleBasic` implementation and core IBC will no longer include either type as registered by default. + +Longer term solutions include using internal module communication as described in [ADR 033](https://github.com/cosmos/cosmos-sdk/blob/main/docs/architecture/adr-033-protobuf-inter-module-comm.md) on the SDK. +The following functions should become callbacks invoked via intermodule communication: + +- `Status` +- `GetTimestampAtHeight` +- `VerifyMembership` +- `VerifyNonMembership` +- `Initialize` +- `VerifyClientMessage` +- `CheckForMisbehaviour` +- `UpdateStateOnMisbehaviour` +- `UpdateState` +- `CheckSubstituteAndUpdateState` +- `VerifyUpgradeAndUpdateState` + +The ClientState interface should eventually be trimmed down to something along the lines of: + +```go +type ClientState interface { + proto.Message + + ClientType() string + GetLatestHeight() Height + Validate() error + + ZeroCustomFields() ClientState + + // ADDITION + Route() string // route used for intermodule communication +} +``` + +For the most part, any functions which require access to the client store should likely not be an interface function of the `ClientState`. + +`ExportMetadata` should eventually be replaced by a light client's ability to import/export it's own genesis information. + +### Intermodule communication + +To keep the transition from interface callbacks to SDK module callbacks as simple as possible, intermodule communication (when available) should be used to route to light client modules. +Without intermodule communication, a routing system would need to be developed/maintained to register callbacks. +This functionality of routing to another SDK module should and will be provided by the SDK. +Once it is possible to route to SDK modules, a `ClientState` type could expose the function `Route` which returns the callback route used to call the light client module. + +## Consequences + +### Positive + +- use a single approach for interacting with callbacks +- greater flexibility and control for IBC light clients +- does not require developing another routing system + +### Negative + +- requires breaking changes +- requires waiting for intermodule communication + +### Neutral + +N/A diff --git a/ibc/next/architecture/adr-011-transfer-total-escrow-state-entry.mdx b/ibc/next/architecture/adr-011-transfer-total-escrow-state-entry.mdx new file mode 100644 index 00000000..a23ae88f --- /dev/null +++ b/ibc/next/architecture/adr-011-transfer-total-escrow-state-entry.mdx @@ -0,0 +1,147 @@ +--- +title: "ADR 011: ICS-20 Transfer State Entry For Total Amount Of Tokens In Escrow" +--- + +## Changelog + +- 24-05-2023: Initial draft + +## Status + +Accepted and applied in v7.1 of ibc-go + +## Context + +Every ICS-20 transfer channel has its own escrow bank account. This account is used to lock tokens that are transferred out of a chain that acts as the source of the tokens (i.e. when the tokens being transferred have not returned to the originating chain). This design makes it easy to query the balance of the escrow accounts and find out the total amount of tokens in escrow in a particular channel. However, there are use cases where it would be useful to determine the total escrowed amount of a given denomination across all channels where those tokens have been transferred out. + +For example: assuming that there are three channels between Cosmos Hub to Osmosis and 10 ATOM have been transferred from the Cosmos Hub to Osmosis on each of those channels, then we would like to know that 30 ATOM have been transferred (i.e. are locked in the escrow accounts of each channel) without needing to iterate over each escrow account to add up the balances of each. + +For a sample use case where this feature would be useful, please refer to Osmosis' rate limiting use case described in [#2664](https://github.com/cosmos/ibc-go/issues/2664). + +## Decision + +### State entry denom -> amount + +The total amount of tokens in escrow (across all transfer channels) for a given denomination is stored in state in an entry keyed by the denomination: `totalEscrowForDenom/{denom}`. + +### Panic if amount is negative + +If a negative amount is ever attempted to be stored, then the keeper function will panic: + +```go +if coin.Amount.IsNegative() { + panic(fmt.Sprintf("amount cannot be negative: %s", coin.Amount)) +} +``` + +### Delete state entry if amount is zero + +When setting the amount for a particular denomination, the value might be zero if all tokens that were transferred out of the chain have been transferred back. If this happens, then the state entry for this particular denomination will be deleted, since Cosmos SDK's `x/bank` module prunes any non-zero balances: + +```go +if coin.Amount.IsZero() { + store.Delete(key) // delete the key since Cosmos SDK x/bank module will prune any non-zero balances + return +} +``` + +### Bundle escrow/unescrow with setting state entry + +Two new functions are implemented that bundle together the operations of escrowing/unescrowing and setting the total escrow amount in state, since these operations need to be executed together. + +For escrowing tokens: + +```go +// escrowToken will send the given token from the provided sender to the escrow address. It will also +// update the total escrowed amount by adding the escrowed token to the current total escrow. +func (k Keeper) escrowToken(ctx sdk.Context, sender, escrowAddress sdk.AccAddress, token sdk.Coin) error { + if err := k.bankKeeper.SendCoins(ctx, sender, escrowAddress, sdk.NewCoins(token)); err != nil { + // failure is expected for insufficient balances + return err + } + + // track the total amount in escrow keyed by denomination to allow for efficient iteration + currentTotalEscrow := k.GetTotalEscrowForDenom(ctx, token.GetDenom()) + newTotalEscrow := currentTotalEscrow.Add(token) + k.SetTotalEscrowForDenom(ctx, newTotalEscrow) + + return nil +} +``` + +For unescrowing tokens: + +```go +// unescrowToken will send the given token from the escrow address to the provided receiver. It will also +// update the total escrow by deducting the unescrowed token from the current total escrow. +func (k Keeper) unescrowToken(ctx sdk.Context, escrowAddress, receiver sdk.AccAddress, token sdk.Coin) error { + if err := k.bankKeeper.SendCoins(ctx, escrowAddress, receiver, sdk.NewCoins(token)); err != nil { + // NOTE: this error is only expected to occur given an unexpected bug or a malicious + // counterparty module. The bug may occur in bank or any part of the code that allows + // the escrow address to be drained. A malicious counterparty module could drain the + // escrow address by allowing more tokens to be sent back then were escrowed. + return errorsmod.Wrap(err, "unable to unescrow tokens, this may be caused by a malicious counterparty module or a bug: please open an issue on counterparty module") + } + + // track the total amount in escrow keyed by denomination to allow for efficient iteration + currentTotalEscrow := k.GetTotalEscrowForDenom(ctx, token.GetDenom()) + newTotalEscrow := currentTotalEscrow.Sub(token) + k.SetTotalEscrowForDenom(ctx, newTotalEscrow) + + return nil +} +``` + +When tokens need to be escrowed in `sendTransfer`, then `escrowToken` is called; when tokens need to be unescrowed on execution of the `OnRecvPacket`, `OnAcknowledgementPacket` or `OnTimeoutPacket` callbacks, then `unescrowToken` is called. + +### gRPC query endpoint and CLI to retrieve amount + +A gRPC query endpoint is added so that it is possible to retrieve the total amount for a given denomination: + +```proto +// TotalEscrowForDenom returns the total amount of tokens in escrow based on the denom. +rpc TotalEscrowForDenom(QueryTotalEscrowForDenomRequest) returns (QueryTotalEscrowForDenomResponse) { + option (google.api.http).get = "/ibc/apps/transfer/v1/denoms/{denom=**}/total_escrow"; +} + +// QueryTotalEscrowForDenomRequest is the request type for TotalEscrowForDenom RPC method. +message QueryTotalEscrowForDenomRequest { + string denom = 1; +} + +// QueryTotalEscrowForDenomResponse is the response type for TotalEscrowForDenom RPC method. +message QueryTotalEscrowForDenomResponse { + cosmos.base.v1beta1.Coin amount = 1 [(gogoproto.nullable) = false]; +} +``` + +And a CLI query is also available to retrieve the total amount via the command line: + +```shell +query ibc-transfer total-escrow [denom] +``` + +## Consequences + +### Positive + +- Possibility to retrieve the total amount of a particular denomination in escrow across all transfer channels without iteration. + +### Negative + +No notable consequences + +### Neutral + +- A new entry is added to state for every denomination that is transferred out of the chain. + +## References + +Issues: + +- [#2664](https://github.com/cosmos/ibc-go/issues/2664) + +PRs: + +- [#3019](https://github.com/cosmos/ibc-go/pull/3019) +- [#3558](https://github.com/cosmos/ibc-go/pull/3558) diff --git a/ibc/next/architecture/adr-015-ibc-packet-receiver.mdx b/ibc/next/architecture/adr-015-ibc-packet-receiver.mdx new file mode 100644 index 00000000..d85ba9b0 --- /dev/null +++ b/ibc/next/architecture/adr-015-ibc-packet-receiver.mdx @@ -0,0 +1,301 @@ +--- +title: "ADR 015: IBC Packet Receiver" +--- + +## Changelog + +- 22-10-2019: Initial Draft + +## Context + +[ICS 26 - Routing Module](https://github.com/cosmos/ibc/tree/master/spec/core/ics-026-routing-module) defines a function [`handlePacketRecv`](https://github.com/cosmos/ibc/tree/master/spec/core/ics-026-routing-module#packet-relay). + +In ICS 26, the routing module is defined as a layer above each application module +which verifies and routes messages to the destination modules. It is possible to +implement it as a separate module, however, we already have the functionality to route +messages upon the destination identifiers in the baseapp. This ADR suggests +to utilize existing `baseapp.router` to route packets to application modules. + +Generally, routing module callbacks have two separate steps in them, +verification and execution. This corresponds to the `AnteHandler`-`Handler` +model inside the SDK. We can do the verification inside the `AnteHandler` +in order to increase developer ergonomics by reducing boilerplate +verification code. + +For atomic multi-message transaction, we want to keep the IBC related +state modification to be preserved even the application side state change +reverts. One of the example might be IBC token sending message following with +stake delegation which uses the tokens received by the previous packet message. +If the token receiving fails for any reason, we might not want to keep +executing the transaction, but we also don't want to abort the transaction +or the sequence and commitment will be reverted and the channel will be stuck. +This ADR suggests new `CodeType`, `CodeTxBreak`, to fix this problem. + +## Decision + +`PortKeeper` will have the capability key that is able to access only the +channels bound to the port. Entities that hold a `PortKeeper` will be +able to call the methods on it which are corresponding with the methods with +the same names on the `ChannelKeeper`, but only with the +allowed port. `ChannelKeeper.Port(string, ChannelChecker)` will be defined to +easily construct a capability-safe `PortKeeper`. This will be addressed in +another ADR and we will use insecure `ChannelKeeper` for now. + +`baseapp.runMsgs` will break the loop over the messages if one of the handlers +returns `!Result.IsOK()`. However, the outer logic will write the cached +store if `Result.IsOK() || Result.Code.IsBreak()`. `Result.Code.IsBreak()` if +`Result.Code == CodeTxBreak`. + +```go +func (app *BaseApp) runTx(tx Tx) (result Result) { + msgs := tx.GetMsgs() + + // AnteHandler + if app.anteHandler != nil { + anteCtx, msCache := app.cacheTxContext(ctx) + newCtx, err := app.anteHandler(anteCtx, tx) + if !newCtx.IsZero() { + ctx = newCtx.WithMultiStore(ms) + } + + if err != nil { + // error handling logic + return res + } + + msCache.Write() + } + + // Main Handler + runMsgCtx, msCache := app.cacheTxContext(ctx) + result = app.runMsgs(runMsgCtx, msgs) + // BEGIN modification made in this ADR + if result.IsOK() || result.IsBreak() { + // END + msCache.Write() + } + + return result +} +``` + +The Cosmos SDK will define an `AnteDecorator` for IBC packet receiving. The +`AnteDecorator` will iterate over the messages included in the transaction, type +`switch` to check whether the message contains an incoming IBC packet, and if so +verify the Merkle proof. + +```go +type ProofVerificationDecorator struct { + clientKeeper ClientKeeper + channelKeeper ChannelKeeper +} + +func (pvr ProofVerificationDecorator) AnteHandle(ctx Context, tx Tx, simulate bool, next AnteHandler) (Context, error) { + for _, msg := range tx.GetMsgs() { + var err error + switch msg := msg.(type) { + case client.MsgUpdateClient: + err = pvr.clientKeeper.UpdateClient(msg.ClientID, msg.Header) + case channel.MsgPacket: + err = pvr.channelKeeper.RecvPacket(msg.Packet, msg.Proofs, msg.ProofHeight) + case channel.MsgAcknowledgement: + err = pvr.channelKeeper.AcknowledgementPacket(msg.Acknowledgement, msg.Proof, msg.ProofHeight) + case channel.MsgTimeoutPacket: + err = pvr.channelKeeper.TimeoutPacket(msg.Packet, msg.Proof, msg.ProofHeight, msg.NextSequenceRecv) + case channel.MsgChannelOpenInit; + err = pvr.channelKeeper.CheckOpen(msg.PortID, msg.ChannelID, msg.Channel) + default: + continue + } + + if err != nil { + return ctx, err + } + } + + return next(ctx, tx, simulate) +} +``` + +Where `MsgUpdateClient`, `MsgPacket`, `MsgAcknowledgement`, `MsgTimeoutPacket` +are `sdk.Msg` types correspond to `handleUpdateClient`, `handleRecvPacket`, +`handleAcknowledgementPacket`, `handleTimeoutPacket` of the routing module, +respectively. + +The side effects of `RecvPacket`, `VerifyAcknowledgement`, +`VerifyTimeout` will be extracted out into separated functions, +`WriteAcknowledgement`, `DeleteCommitment`, `DeleteCommitmentTimeout`, respectively, +which will be called by the application handlers after the execution. + +`WriteAcknowledgement` writes the acknowledgement to the state that can be +verified by the counter-party chain and increments the sequence to prevent +double execution. `DeleteCommitment` will delete the commitment stored, +`DeleteCommitmentTimeout` will delete the commitment and close channel in case +of ordered channel. + +```go +func (keeper ChannelKeeper) WriteAcknowledgement(ctx Context, packet Packet, ack []byte) { + keeper.SetPacketAcknowledgement(ctx, packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence(), ack) + keeper.SetNextSequenceRecv(ctx, packet.GetDestPort(), packet.GetDestChannel(), packet.GetSequence()) +} + +func (keeper ChannelKeeper) DeleteCommitment(ctx Context, packet Packet) { + keeper.deletePacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) +} + +func (keeper ChannelKeeper) DeleteCommitmentTimeout(ctx Context, packet Packet) { + k.deletePacketCommitment(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetSequence()) + + if channel.Ordering == types.ORDERED [ + channel.State = types.CLOSED + k.SetChannel(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), channel) + } +} +``` + +Each application handler should call respective finalization methods on the `PortKeeper` +in order to increase sequence (in case of packet) or remove the commitment +(in case of acknowledgement and timeout). +Calling those functions implies that the application logic has successfully executed. +However, the handlers can return `Result` with `CodeTxBreak` after calling those methods +which will persist the state changes that has been already done but prevent any further +messages to be executed in case of semantically invalid packet. This will keep the sequence +increased in the previous IBC packets(thus preventing double execution) without +proceeding to the following messages. +In any case the application modules should never return state reverting result, +which will make the channel unable to proceed. + +`ChannelKeeper.CheckOpen` method will be introduced. This will replace `onChanOpen*` defined +under the routing module specification. Instead of define each channel handshake callback +functions, application modules can provide `ChannelChecker` function with the `AppModule` +which will be injected to `ChannelKeeper.Port()` at the top level application. +`CheckOpen` will find the correct `ChannelChecker` using the +`PortID` and call it, which will return an error if it is unacceptable by the application. + +The `ProofVerificationDecorator` will be inserted to the top level application. +It is not safe to make each module responsible to call proof verification +logic, whereas application can misbehave(in terms of IBC protocol) by +mistake. + +The `ProofVerificationDecorator` should come right after the default sybil attack +resistant layer from the current `auth.NewAnteHandler`: + +```go +// add IBC ProofVerificationDecorator to the Chain of +func NewAnteHandler( + ak keeper.AccountKeeper, supplyKeeper types.SupplyKeeper, ibcKeeper ibc.Keeper, + sigGasConsumer SignatureVerificationGasConsumer) sdk.AnteHandler { + return sdk.ChainAnteDecorators( + NewSetUpContextDecorator(), // outermost AnteDecorator. SetUpContext must be called first + ... + NewIncrementSequenceDecorator(ak), + ibcante.ProofVerificationDecorator(ibcKeeper.ClientKeeper, ibcKeeper.ChannelKeeper), // innermost AnteDecorator + ) +} +``` + +The implementation of this ADR will also create a `Data` field of the `Packet` of type `[]byte`, which can be deserialised by the receiving module into its own private type. It is up to the application modules to do this according to their own interpretation, not by the IBC keeper. This is crucial for dynamic IBC. + +Example application-side usage: + +```go +type AppModule struct {} + +// CheckChannel will be provided to the ChannelKeeper as ChannelKeeper.Port(module.CheckChannel) +func (module AppModule) CheckChannel(portID, channelID string, channel Channel) error { + if channel.Ordering != UNORDERED { + return ErrUncompatibleOrdering() + } + if channel.CounterpartyPort != "bank" { + return ErrUncompatiblePort() + } + if channel.Version != "" { + return ErrUncompatibleVersion() + } + return nil +} + +func NewHandler(k Keeper) Handler { + return func(ctx Context, msg Msg) Result { + switch msg := msg.(type) { + case MsgTransfer: + return handleMsgTransfer(ctx, k, msg) + case ibc.MsgPacket: + var data PacketDataTransfer + if err := types.ModuleCodec.UnmarshalBinaryBare(msg.GetData(), &data); err != nil { + return err + } + return handlePacketDataTransfer(ctx, k, msg, data) + case ibc.MsgTimeoutPacket: + var data PacketDataTransfer + if err := types.ModuleCodec.UnmarshalBinaryBare(msg.GetData(), &data); err != nil { + return err + } + return handleTimeoutPacketDataTransfer(ctx, k, packet) + // interface { PortID() string; ChannelID() string; Channel() ibc.Channel } + // MsgChanInit, MsgChanTry implements ibc.MsgChannelOpen + case ibc.MsgChannelOpen: + return handleMsgChannelOpen(ctx, k, msg) + } + } +} + +func handleMsgTransfer(ctx Context, k Keeper, msg MsgTransfer) Result { + err := k.SendTransfer(ctx,msg.PortID, msg.ChannelID, msg.Amount, msg.Sender, msg.Receiver) + if err != nil { + return sdk.ResultFromError(err) + } + + return sdk.Result{} +} + +func handlePacketDataTransfer(ctx Context, k Keeper, packet Packet, data PacketDataTransfer) Result { + err := k.ReceiveTransfer(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetDestinationPort(), packet.GetDestinationChannel(), data) + if err != nil { + // TODO: Source chain sent invalid packet, shutdown channel + } + k.ChannelKeeper.WriteAcknowledgement([]byte{0x00}) // WriteAcknowledgement increases the sequence, preventing double spending + return sdk.Result{} +} + +func handleCustomTimeoutPacket(ctx Context, k Keeper, packet CustomPacket) Result { + err := k.RecoverTransfer(ctx, packet.GetSourcePort(), packet.GetSourceChannel(), packet.GetDestinationPort(), packet.GetDestinationChannel(), data) + if err != nil { + // This chain sent invalid packet or cannot recover the funds + panic(err) + } + k.ChannelKeeper.DeleteCommitmentTimeout(ctx, packet) + // packet timeout should not fail + return sdk.Result{} +} + +func handleMsgChannelOpen(sdk.Context, k Keeper, msg MsgOpenChannel) Result { + k.AllocateEscrowAddress(ctx, msg.ChannelID()) + return sdk.Result{} +} +``` + +## Status + +Proposed + +## Consequences + +### Positive + +- Intuitive interface for developers - IBC handlers do not need to care about IBC authentication +- State change commitment logic is embedded into `baseapp.runTx` logic + +### Negative + +- Cannot support dynamic ports, routing is tied to the baseapp router + +### Neutral + +- Introduces new `AnteHandler` decorator. +- Dynamic ports can be supported using hierarchical port identifier, see #5290 for detail + +## References + +- Relevant comment: [cosmos/ics#289](https://github.com/cosmos/ibc/issues/289#issuecomment-544533583) +- [ICS26 - Routing Module](https://github.com/cosmos/ibc/tree/master/spec/core/ics-026-routing-module) diff --git a/ibc/next/architecture/adr-025-ibc-passive-channels.mdx b/ibc/next/architecture/adr-025-ibc-passive-channels.mdx new file mode 100644 index 00000000..84e4710b --- /dev/null +++ b/ibc/next/architecture/adr-025-ibc-passive-channels.mdx @@ -0,0 +1,143 @@ +--- +title: "ADR 025: IBC Passive Channels" +--- + +## Changelog + +- 23-04-2021: Change status to "deprecated" +- 23-05-2020: Provide sample Go code and more details +- 18-05-2020: Initial Draft + +## Status + +*deprecated* + +## Context + +The current "naive" IBC Relayer strategy currently establishes a single predetermined IBC channel atop a single connection between two clients (each potentially of a different chain). This strategy then detects packets to be relayed by watching for `send_packet` and `recv_packet` events matching that channel, and sends the necessary transactions to relay those packets. + +We wish to expand this "naive" strategy to a "passive" one which detects and relays both channel handshake messages and packets on a given connection, without the need to know each channel in advance of relaying it. + +In order to accomplish this, we propose adding more comprehensive events to expose channel metadata for each transaction sent from the `x/ibc/core/04-channel/keeper/handshake.go` and `x/ibc/core/04-channel/keeper/packet.go` modules. + +Here is an example of what would be in `ChanOpenInit`: + +```go +const ( + EventTypeChannelMeta = "channel_meta" + AttributeKeyAction = "action" + AttributeKeyHops = "hops" + AttributeKeyOrder = "order" + AttributeKeySrcPort = "src_port" + AttributeKeySrcChannel = "src_channel" + AttributeKeySrcVersion = "src_version" + AttributeKeyDstPort = "dst_port" + AttributeKeyDstChannel = "dst_channel" + AttributeKeyDstVersion = "dst_version" +) +// ... +// Emit Event with Channel metadata for the relayer to pick up and +// relay to the other chain +// This appears immediately before the successful return statement. +ctx.EventManager().EmitEvents(sdk.Events{ + sdk.NewEvent( + types.EventTypeChannelMeta, + sdk.NewAttribute(types.AttributeKeyAction, "open_init"), + sdk.NewAttribute(types.AttributeKeySrcConnection, connectionHops[0]), + sdk.NewAttribute(types.AttributeKeyHops, strings.Join(connectionHops, ",")), + sdk.NewAttribute(types.AttributeKeyOrder, order.String()), + sdk.NewAttribute(types.AttributeKeySrcPort, portID), + sdk.NewAttribute(types.AttributeKeySrcChannel, channelID), + sdk.NewAttribute(types.AttributeKeySrcVersion, version), + sdk.NewAttribute(types.AttributeKeyDstPort, counterparty.GetPortID()), + sdk.NewAttribute(types.AttributeKeyDstChannel, counterparty.GetChannelID()), + // The destination version is not yet known, but a value is necessary to pad + // the event attribute offsets + sdk.NewAttribute(types.AttributeKeyDstVersion, ""), + ), +}) +``` + +These metadata events capture all the "header" information needed to route IBC channel handshake transactions without requiring the client to query any data except that of the connection ID that it is willing to relay. It is intended that `channel_meta.src_connection` is the only event key that needs to be indexed for a passive relayer to function. + +### Handling Channel Open Attempts + +In the case of the passive relayer, when one chain sends a `ChanOpenInit`, the relayer should inform the other chain of this open attempt and allow that chain to decide how (and if) it continues the handshake. Once both chains have actively approved the channel opening, then the rest of the handshake can happen as it does with the current "naive" relayer. + +To implement this behavior, we propose replacing the `cbs.OnChanOpenTry` callback with a new `cbs.OnAttemptChanOpenTry` callback which explicitly handles the `MsgChannelOpenTry`, usually by resulting in a call to `keeper.ChanOpenTry`. The typical implementation, in `x/ibc-transfer/module.go` would be compatible with the current "naive" relayer, as follows: + +```go +func (am AppModule) OnAttemptChanOpenTry( + ctx sdk.Context, + chanKeeper channel.Keeper, + portCap *capability.Capability, + msg channel.MsgChannelOpenTry, +) (*sdk.Result, error) { + // Require portID is the portID transfer module is bound to + boundPort := am.keeper.GetPort(ctx) + if boundPort != msg.PortID { + return nil, sdkerrors.Wrapf(porttypes.ErrInvalidPort, "invalid port: %s, expected %s", msg.PortID, boundPort) + } + + // BEGIN NEW CODE + // Assert our protocol version, overriding the relayer's suggestion. + msg.Version = types.Version + // Continue the ChanOpenTry. + res, chanCap, err := channel.HandleMsgChannelOpenTry(ctx, chanKeeper, portCap, msg) + if err != nil { + return nil, err + } + // END OF NEW CODE + + // ... the rest of the callback is similar to the existing OnChanOpenTry + // but uses msg.* directly. +``` + +Here is how this callback would be used, in the implementation of `x/ibc/handler.go`: + +```go +// ... +case channel.MsgChannelOpenTry: + // Lookup module by port capability + module, portCap, err := k.PortKeeper.LookupModuleByPort(ctx, msg.PortID) + if err != nil { + return nil, sdkerrors.Wrap(err, "could not retrieve module from port-id") + } + // Retrieve callbacks from router + cbs, ok := k.Router.GetRoute(module) + if !ok { + return nil, sdkerrors.Wrapf(port.ErrInvalidRoute, "route not found to module: %s", module) + } + // Delegate to the module's OnAttemptChanOpenTry. + return cbs.OnAttemptChanOpenTry(ctx, k.ChannelKeeper, portCap, msg) +``` + +The reason we do not have a more structured interaction between `x/ibc/handler.go` and the port's module (to explicitly negotiate versions, etc) is that we do not wish to constrain the app module to have to finish handling the `MsgChannelOpenTry` during this transaction or even this block. + +## Decision + +- Expose events to allow "passive" connection relayers. +- Enable application-initiated channels via such passive relayers. +- Allow port modules to control how to handle open-try messages. + +## Consequences + +### Positive + +Makes channels into a complete application-level abstraction. + +Applications have full control over initiating and accepting channels, rather than expecting a relayer to tell them when to do so. + +A passive relayer does not have to know what kind of channel (version string, ordering constraints, firewalling logic) the application supports. These are negotiated directly between applications. + +### Negative + +Increased event size for IBC messages. + +### Neutral + +More IBC events are exposed. + +## References + +- The Agoric VM's IBC handler currently [accommodates `attemptChanOpenTry`](https://github.com/Agoric/agoric-sdk/blob/904b3a0423222a1b32893453e44bbde598473960/packages/cosmic-swingset/lib/ag-solo/vats/ibc.js#L546) diff --git a/ibc/next/architecture/adr-026-ibc-client-recovery-mechanisms.mdx b/ibc/next/architecture/adr-026-ibc-client-recovery-mechanisms.mdx new file mode 100644 index 00000000..6a22b53a --- /dev/null +++ b/ibc/next/architecture/adr-026-ibc-client-recovery-mechanisms.mdx @@ -0,0 +1,92 @@ +--- +title: "ADR 026: IBC Client Recovery Mechanisms" +--- + +## Changelog + +- 23-06-2020: Initial version +- 06-08-2020: Revisions per review & to reference version +- 15-01-2021: Revision to support substitute clients for unfreezing +- 20-05-2021: Revision to simplify consensus state copying, remove initial height +- 08-04-2022: Revision to deprecate AllowUpdateAfterExpiry and AllowUpdateAfterMisbehaviour +- 15-07-2022: Revision to allow updating of TrustingPeriod +- 05-09-2023: Revision to migrate from gov v1beta1 to gov v1 + +## Status + +*Accepted* + +## Context + +### Summary + +At launch, IBC will be a novel protocol, without an experienced user-base. At the protocol layer, it is not possible to distinguish between client expiry or misbehaviour due to genuine faults (Byzantine behaviour) and client expiry or misbehaviour due to user mistakes (failing to update a client, or accidentally double-signing). In the base IBC protocol and ICS 20 fungible token transfer implementation, if a client can no longer be updated, funds in that channel will be permanently locked and can no longer be transferred. To the degree that it is safe to do so, it would be preferable to provide users with a recovery mechanism which can be utilised in these exceptional cases. + +### Exceptional cases + +The state of concern is where a client associated with connection(s) and channel(s) can no longer be updated. This can happen for several reasons: + +1. The chain which the client is following has halted and is no longer producing blocks/headers, so no updates can be made to the client +1. The chain which the client is following has continued to operate, but no relayer has submitted a new header within the unbonding period, and the client has expired + 1. This could be due to real misbehaviour (intentional Byzantine behaviour) or merely a mistake by validators, but the client cannot distinguish these two cases +1. The chain which the client is following has experienced a misbehaviour event, and the client has been frozen & thus can no longer be updated + +### Security model + +Two-thirds of the validator set (the quorum for governance, module participation) can already sign arbitrary data, so allowing governance to manually force-update a client with a new header after a delay period does not substantially alter the security model. + +## Decision + +We elect not to deal with chains which have actually halted, which is necessarily Byzantine behaviour and in which case token recovery is not likely possible anyways (in-flight packets cannot be timed-out, but the relative impact of that is minor). + +1. Require Tendermint light clients (ICS 07) to be created with the following additional flags + 1. `allow_update_after_expiry` (boolean, default true). Note that this flag has been deprecated, it remains to signal intent but checks against this value will not be enforced. +1. Require Tendermint light clients (ICS 07) to expose the following additional internal query functions + 1. `Expired() boolean`, which returns whether or not the client has passed the trusting period since the last update (in which case no headers can be validated) +1. Require Tendermint light clients (ICS 07) & solo machine clients (ICS 06) to be created with the following additional flags + 1. `allow_update_after_misbehaviour` (boolean, default true). Note that this flag has been deprecated, it remains to signal intent but checks against this value will not be enforced. +1. Require Tendermint light clients (ICS 07) to expose the following additional state mutation functions + 1. `Unfreeze()`, which unfreezes a light client after misbehaviour and clears any frozen height previously set +1. Add a new governance proposal with `MsgRecoverClient`. + 1. Create a new Msg with two client identifiers (`string`) and a signer. + 1. The first client identifier is the proposed client to be updated. This client must be either frozen or expired. + 1. The second client is a substitute client. It carries all the state for the client which may be updated. It must have identical client and chain parameters to the client which may be updated (except for latest height, frozen height, and chain-id). It should be continually updated during the voting period. + 1. If this governance proposal passes, the client on trial will be updated to the latest state of the substitute. + 1. The signer must be the authority set for the ibc module. + + Previously, `AllowUpdateAfterExpiry` and `AllowUpdateAfterMisbehaviour` were used to signal the recovery options for an expired or frozen client, and governance proposals were not allowed to overwrite the client if these parameters were set to false. However, this has now been deprecated because a code migration can overwrite the client and consensus states regardless of the value of these parameters. If governance would vote to overwrite a client or consensus state, it is likely that governance would also be willing to perform a code migration to do the same. + + In addition, `TrustingPeriod` was initially not allowed to be updated by a client upgrade proposal. However, due to the number of situations experienced in production where the `TrustingPeriod` of a client should be allowed to be updated because of ie: initial misconfiguration for a canonical channel, governance should be allowed to update this client parameter. + + In versions older than ibc-go v8, `MsgRecoverClient` was a governance proposal type `ClientUpdateProposal`. It has been removed and replaced by `MsgRecoverClient` in the migration from governance v1beta1 to governance v1. + + Note that this should NOT be lightly updated, as there may be a gap in time between when misbehaviour has occurred and when the evidence of misbehaviour is submitted. For example, if the `UnbondingPeriod` is 2 weeks and the `TrustingPeriod` has also been set to two weeks, a validator could wait until right before `UnbondingPeriod` finishes, submit false information, then unbond and exit without being slashed for misbehaviour. Therefore, we recommend that the trusting period for the 07-tendermint client be set to 2/3 of the `UnbondingPeriod`. + +Note that clients frozen due to misbehaviour must wait for the evidence to expire to avoid becoming refrozen. + +This ADR does not address planned upgrades, which are handled separately as per the [specification](https://github.com/cosmos/ibc/tree/master/spec/client/ics-007-tendermint-client#upgrades). + +## Consequences + +### Positive + +- Establishes a mechanism for client recovery in the case of expiry +- Establishes a mechanism for client recovery in the case of misbehaviour +- Constructing an ClientUpdate Proposal is as difficult as creating a new client + +### Negative + +- Additional complexity in client creation which must be understood by the user +- Coping state of the substitute adds complexity +- Governance participants must vote on a substitute client + +### Neutral + +No neutral consequences. + +## References + +- [Prior discussion](https://github.com/cosmos/ibc/issues/421) +- [Epoch number discussion](https://github.com/cosmos/ibc/issues/439) +- [Upgrade plan discussion](https://github.com/cosmos/ibc/issues/445) +- [Migration from gov v1beta1 to gov v1](https://github.com/cosmos/ibc-go/issues/3672) diff --git a/ibc/next/architecture/adr-027-ibc-wasm.mdx b/ibc/next/architecture/adr-027-ibc-wasm.mdx new file mode 100644 index 00000000..20d3421c --- /dev/null +++ b/ibc/next/architecture/adr-027-ibc-wasm.mdx @@ -0,0 +1,169 @@ +--- +title: "ADR 27: Add Support For Wasm Based Light Client" +--- + +## Changelog + +- 26-11-2020: Initial Draft +- 26-05-2023: Update after 02-client refactor and re-implementation by Strangelove +- 13-12-2023: Update after upstreaming of module to ibc-go + +## Status + +*Accepted and applied in v0.1.0 of 08-wasm* + +## Abstract + +In the Cosmos SDK light clients are currently hardcoded in Go. This makes upgrading existing IBC light clients or +adding support for new light client a multi step process involving on-chain governance which is time-consuming. + +To remedy this, we are proposing a Wasm VM to host light client bytecode, which allows easier upgrading of +existing IBC light clients as well as adding support for new IBC light clients without requiring a code release and +corresponding hard-fork event. + +## Context + +Currently in ibc-go light clients are defined as part of the codebase and are implemented as modules under +`modules/light-clients`. Adding support for new light clients or updating an existing light client in the event +of a security issue or consensus update is a multi-step process which is both time-consuming and error-prone. +In order to enable new IBC light client implementations it is necessary to modify the codebase of ibc-go (if the light +client is part of its codebase), re-build chains' binaries, pass a governance proposal and validators upgrade their nodes. + +Another problem stemming from the above process is that if a chain wants to upgrade its own consensus, it will +need to convince every chain or hub connected to it to upgrade its light client in order to stay connected. Due +to the time-consuming process required to upgrade a light client, a chain with lots of connections needs to be +disconnected for quite some time after upgrading its consensus, which can be very expensive in terms of time and effort. + +We are proposing simplifying this workflow by integrating a Wasm light client module that makes adding support for +new light clients a simple governance-gated transaction. The light client bytecode, written in Wasm-compilable Rust, +runs inside a Wasm VM. The Wasm light client submodule exposes a proxy light client interface that routes incoming +messages to the appropriate handler function, inside the Wasm VM for execution. + +With the Wasm light client module, anybody can add new IBC light client in the form of Wasm bytecode (provided they are +able to submit the governance proposal transaction and that it passes) as well as instantiate clients using any created +client type. This allows any chain to update its own light client in other chains without going through the steps outlined above. + +## Decision + +We decided to implement the Wasm light client module as a light client proxy that will interface with the actual light client +uploaded as Wasm bytecode. To enable usage of the Wasm light client module, users need to add it to the list of allowed clients +by updating the `AllowedClients` parameter in the 02-client submodule of core IBC. + +```go +params := clientKeeper.GetParams(ctx) +params.AllowedClients = append(params.AllowedClients, exported.Wasm) +clientKeeper.SetParams(ctx, params) +``` + +Adding a new light client contract is governance-gated. To upload a new light client users need to submit +a [governance v1 proposal](/sdk/v0.53/build/modules/gov#proposals) that contains the `sdk.Msg` for storing +the Wasm contract's bytecode. The required message is `MsgStoreCode` and the bytecode is provided in the field `wasm_byte_code`: + +```proto +// MsgStoreCode defines the request type for the StoreCode rpc. +message MsgStoreCode { + // signer address + string signer = 1; + // wasm byte code of light client contract. It can be raw or gzip compressed + bytes wasm_byte_code = 2; +} +``` + +The RPC handler processing `MsgStoreCode` will make sure that the signer of the message matches the address of authority allowed to +submit this message (which is normally the address of the governance module). + +```go +// StoreCode defines a rpc handler method for MsgStoreCode +func (k Keeper) StoreCode(goCtx context.Context, msg *types.MsgStoreCode) (*types.MsgStoreCodeResponse, error) { + if k.GetAuthority() != msg.Signer { + return nil, errorsmod.Wrapf(ibcerrors.ErrUnauthorized, "expected %s, got %s", k.GetAuthority(), msg.Signer) + } + + ctx := sdk.UnwrapSDKContext(goCtx) + checksum, err := k.storeWasmCode(ctx, msg.WasmByteCode, ibcwasm.GetVM().StoreCode) + if err != nil { + return nil, errorsmod.Wrap(err, "failed to store wasm bytecode") + } + + emitStoreWasmCodeEvent(ctx, checksum) + + return &types.MsgStoreCodeResponse{ + Checksum: checksum, + }, nil +} +``` + +The contract's bytecode is not stored in state (it is actually unnecessary and wasteful to store it, since +the Wasm VM already stores it and can be queried back, if needed). The checksum is simply the hash of the bytecode +of the contract and it is stored in state in an entry with key `checksums` that contains the checksums for the bytecodes that have been stored. + +### How light client proxy works? + +The light client proxy behind the scenes will call a CosmWasm smart contract instance with incoming arguments serialized +in JSON format with appropriate environment information. Data returned by the smart contract is deserialized and +returned to the caller. + +Consider the example of the `VerifyClientMessage` function of `ClientState` interface. Incoming arguments are +packaged inside a payload object that is then JSON serialized and passed to `queryContract`, which executes `WasmVm.Query` +and returns the slice of bytes returned by the smart contract. This data is deserialized and passed as return argument. + +```go +type QueryMsg struct { + Status *StatusMsg `json:"status,omitempty"` + ExportMetadata *ExportMetadataMsg `json:"export_metadata,omitempty"` + TimestampAtHeight *TimestampAtHeightMsg `json:"timestamp_at_height,omitempty"` + VerifyClientMessage *VerifyClientMessageMsg `json:"verify_client_message,omitempty"` + CheckForMisbehaviour *CheckForMisbehaviourMsg `json:"check_for_misbehaviour,omitempty"` +} + +type verifyClientMessageMsg struct { + ClientMessage *ClientMessage `json:"client_message"` +} + +// VerifyClientMessage must verify a ClientMessage. +// A ClientMessage could be a Header, Misbehaviour, or batch update. +// It must handle each type of ClientMessage appropriately. +// Calls to CheckForMisbehaviour, UpdateStaåte, and UpdateStateOnMisbehaviour +// will assume that the content of the ClientMessage has been verified +// and can be trusted. An error should be returned +// if the ClientMessage fails to verify. +func (cs ClientState) VerifyClientMessage( + ctx sdk.Context, + _ codec.BinaryCodec, + clientStore storetypes.KVStore, + clientMsg exported.ClientMessage +) error { + clientMessage, ok := clientMsg.(*ClientMessage) + if !ok { + return errorsmod.Wrapf(ibcerrors.ErrInvalidType, "expected type: %T, got: %T", &ClientMessage{}, clientMsg) + } + + payload := QueryMsg{ + VerifyClientMessage: &VerifyClientMessageMsg{ClientMessage: clientMessage.Data}, + } + _, err := wasmQuery[EmptyResult](ctx, clientStore, &cs, payload) + return err +} +``` + +### Global Wasm VM variable + +The 08-wasm keeper structure keeps a reference to the Wasm VM instantiated in the keeper constructor function. The keeper uses +the Wasm VM to store the bytecode of light client contracts. However, the Wasm VM is also needed in the 08-wasm implementations of +some of the `ClientState` interface functions to initialise a contract, execute calls on the contract and query the contract. Since +the `ClientState` functions do not have access to the 08-wasm keeper, then it has been decided to keep a global pointer variable that +points to the same instance as the one in the 08-wasm keeper. This global pointer variable is then used in the implementations of +the `ClientState` functions. + +## Consequences + +### Positive + +- Adding support for new light client or upgrading existing light client is way easier than before and only requires single transaction instead of a hard-fork. +- Improves maintainability of ibc-go, since no change in codebase is required to support new client or upgrade it. +- The existence of support for Rust dependencies in light clients which may not exist in Go. + +### Negative + +- Light clients written in Rust need to be written in a subset of Rust which could compile in Wasm. +- Introspecting light client code is difficult as only compiled bytecode exists in the blockchain. diff --git a/ibc/next/architecture/adr.template.mdx b/ibc/next/architecture/adr.template.mdx new file mode 100644 index 00000000..d5ec7fc1 --- /dev/null +++ b/ibc/next/architecture/adr.template.mdx @@ -0,0 +1,38 @@ +# ADR \{ADR-NUMBER\}: \{TITLE\} + +## Changelog + +- \{date\}: \{changelog\} + +## Status + +> A decision may be "proposed" if it hasn't been agreed upon yet, or "accepted" once it is agreed upon. If a later ADR changes or reverses a decision, it may be marked as "deprecated" or "superseded" with a reference to its replacement. + +\{Deprecated|Proposed|Accepted\} + +## Context + +> This section contains all the context one needs to understand the current state, and why there is a problem. It should be as succinct as possible and introduce the high-level idea behind the solution. + +## Decision + +> This section explains all of the details of the proposed solution, including implementation details. +It should also describe affects / corollary items that may need to be changed as a part of this. +If the proposed change will be large, please also indicate a way to do the change to maximize ease of review. +(e.g. the optimal split of things to do between separate PR's) + +## Consequences + +> This section describes the consequences, after applying the decision. All consequences should be summarized here, not just the "positive" ones. + +### Positive + +### Negative + +### Neutral + +## References + +> Are there any relevant PR comments, issues that led up to this, or articles referenced for why we made the given design choice? If so link them here! + +- \{reference link\} diff --git a/ibc/next/spec/IBC_V2/README.mdx b/ibc/next/spec/IBC_V2/README.mdx new file mode 100644 index 00000000..a5e20276 --- /dev/null +++ b/ibc/next/spec/IBC_V2/README.mdx @@ -0,0 +1,204 @@ +--- +title: IBC v2 +stage: experimental +version_compatibility: + - ibc-go v10.0.0 +authors: + - name: Aditya Sripal + email: aditya@interchainlabs.io +created: 2024-08-15 +--- + +### Introduction + +IBC v2 is an end-to-end protocol for reliable, authenticated communication between modules on separate distributed ledgers. IBC makes NO assumptions about the consensus algorithm or the state machine. So long as the distributed ledger satisfies the minimal requirements in [ICS-24 Host Requirements](../core/ics-024-host-requirements/README), it can support the IBC v2 protocol and communicate across any application in the IBC v2 network. + +The IBC v2 protocol can be conceptualized in three distinct layers: **IBC CLIENTS**, **IBC CORE**, and **IBC APPS**. **IBC APPS** are the modules that wish to communicate with each other across different ledgers in the IBC v2 network. On example is ICS-20 fungible token transfer which facilitates sending tokens securely from one ledger to another by sending token packet data using **IBC CORE** and executing escrow/mint logic upon sending/receiving the ICS-20 token packet data from counterparty ICS20 applications. +**IBC CLIENTS** identifies and verifies the state of the counterparty ledger. An **IBC CLIENT** is responsible for tracking updates to the state machine and verifying state against a given update. +**IBC CORE** is the handler that implements the transport, authentication, and ordering semantics (hereafter `IBC/TAO`), it **uses** the **IBC CLIENT** to authenticate the packet and then sends the application packet data to the **IBC APP** which will handle the application data. Thus, each layer has a specific isolated responsibility. The **IBC CLIENT** only needs to verify key/value proofs of the counterparty state. The **IBC APP** only needs to process application data coming from a counterparty application. **IBC CORE** enables authenticated IBC packet flow of `SendPacket`, `RecvPacket`, `AcknowledgePacket`, `TimeoutPacket` for the **IBC APP** using the **IBC CLIENT** as a verification oracle. + +The goal of this document is to provide a basic overview of the IBC V2 protocol. Where appropriate, distinctions from IBC v1 will be highlighted. For a detailed specification of each layer please refer to the ICS-standards. + +### Specification + +### IBC Clients + +The IBC Client keeps track of counterparty state updates and exposes a verifier of the counterparty state to **IBC CORE**. An IBC client implementation achieves this through the use of two distinct structures: the `ClientState` and the `ConsensusState`. From the perspective of IBC, these are opaque bytes and are defined by the specific light client implementation. The `ClientState` is intended to encapsulate parameters of the counterparty consensus that SHOULD NOT change across heights, this can include a chain identifier and security parameters like a staking unbonding period. The `ConsensusState` on the other hand is a **view** or a snapshot of the counterparty consensus at a particular height. This **view** in almost all cases will be a highly compressed view of the counterparty consensus. The **IBC CLIENT** will not store the entire state of the counterparty chain, nor will it execute all transactions of the counterparty chain as this would be equivalent to hosting a full node. A common pattern is to have the counterparty Consensus to create a Merklized commitment of the counterparty state on each state update. The **IBC CLIENT** can add the merkle root hash to the `ConsensusState` and then verify membership/nonmembership proofs against the root hash in the stored consensus state. + +The **IBC CLIENT** encapsulates a particular security model, this can be anything from a multisign bridge committee to a fully verified light client of the counterparty consensus algorithm. It is up to users sending packets on the client to decide whether the security model is acceptable to them or not. +The IBC client is responsible for taking an initial view of the counterparty consensus, and updating that view from this trusted point using the security model instantiated in the client. This initial counterparty consensus is trusted axiomatically. Thus, IBC does not have any **in-protocol** awareness of which chain a particular client is verifying. A user can inspect a client and verify for themselves that the client is tracking the chain that they care about (i.e. validating a specific consensus state matches the consensus output of the desired counterparty chain) and that the parameters of the security model encoded in the `ClientState` are satisfactory. A user need only verify the client once, either by themselves or through social consensus, once that initial trust is established; the **IBC CLIENT** MUST continue updating the view of the counterparty state from previously trusted views given the parameterized security model. Thus, once a user trusts a light client they can be guaranteed that the trust will not be violated by the client. + +If the security model is violated by counterparty consensus, the **IBC CLIENT** implementation MUST provide the ability to freeze the client and prevent further updates and verification. The evidence for this violation is called `Misbehaviour` and upon verification the client is frozen and all packet processing against the client is paused. Any damage already done cannot be automatically reverted in-protocol, however this mechanism ensures the attack is stopped as soon as possible so that an out-of-band recovery mechanism can intervene (e.g. governance). This recovery mechanism should ensure the consensus violation is corrected on the counterparty and any invalid state is reverted to the extent possible before resuming packet processing by unfreezing the client. + +The **IBC CLIENT** **must** have external endpoints for relayers (off-chain processes that have full-node access to other chains in the network) to initialize a client, update the client, and submit misbehaviour. + +The implementation of each of these endpoints will be specific to the particular consensus mechanism targeted. The choice of consensus algorithm itself is arbitrary, it may be a Proof-of-Stake algorithm like CometBFT, or a multisig of trusted authorities, or a rollup that relies on an additional underlying client in order to verify its consensus. However, a light client must have the ability to define finality for a given snapshot of the state machine, this may be either through single-slot finality or a finality gadget. + +Thus, the endpoints themselves should accept arbitrary bytes for the arguments passed into these client endpoints as it is up to each individual client implementation to unmarshal these bytes into the structures they expect. + +```typescript +// initializes client with a starting client state containing all light client parameters +// and an initial consensus state that will act as a trusted seed from which to verify future headers +function createClient( + clientState: bytes, + consensusState: bytes, +): (id: bytes, err: error) + +// once a client has been created, it can be referenced with the identifier and passed the header +// to keep the client up-to-date. In most cases, this will cause a new consensus state derived from the header +// to be stored in the client +function updateClient( + clientId: bytes, + header: bytes, +): error + +// once a client has been created, relayers can submit misbehaviour that proves the counterparty chain violated the trust model. +// The light client must verify the misbehaviour using the trust model of the consensus mechanism +// and execute some custom logic such as freezing the client from accepting future updates and proof verification. +function submitMisbehaviour( + clientId: bytes, + misbehaviour: bytes, +): error +``` + +As relayers keep the client up-to-date and add `ConsensusState`s to the client, **IBC CORE** will use the exposed verification endpoints: `VerifyMembership` and `VerifyNonMembership` to verify incoming packet-flow messages coming from the counterparty. + +```typescript +// verifies a membership of a path and value in the counterparty chain identified by the provided clientId +// against a particular ConsensusState identified by the provided height +function verifyMembership( + clientId: bytes, + height: Number, + proof: bytes, + path: CommitmentPath, + value: bytes +): error + +// verifies the nonmembership of a path in the counterparty chain identified by the provided clientId +// against a particular ConsensusState identified by the provided height +function verifyNonMembership( + cliendId: bytes, + height: Number, + proof: bytes, + path: CommitmentPath +): error +``` + +### Core IBC Functionality + +IBC in its essence is the ability for applications on different blockchains with different consensus mechanisms to communicate with each other through client backed security. Thus, IBC needs the client described above and the IBC applications that define the packet data they wish to send and receive. + +In addition to these layers, IBC v1 introduced the connection and channel abstractions to connect these two fundamental layers. IBC v2 intends to compress only the necessary aspects of connection and channel layers into a single packet handler with no handshakes but before doing this it is critical to understand what service they currently provide. + +Properties of IBC v1 Connection: + +- Verifies the validity of the counterparty client +- Establishes a unique identifier on each side for a shared abstract understanding (the connection) +- Establishes an agreement on the IBC version and supported features +- Allows multiple connections to be built against the same client pair +- Establishes the delay period so this security parameter can be instantiated differently for different connections against the same client pairing. +- Defines which channel orderings are supported + +Properties of IBC v1 Channel: + +- Separates applications into dedicated 1-1 communication channels. This prevents applications from writing into each other's channels. +- Allows applications to come to agreement on the application parameters (version negotiation). Ensures that each side can understand the other's communication and that they are running mutually compatible logic. This version negotiation is a multi-step process that allows the finalized version to differ substantially from the one initially proposed +- Establishes the ordering of the channel +- Establishes unique identifiers for the applications on either chain to use to reference each other when sending and receiving packets. +- The application protocol can be continually upgraded over time by using the upgrade handshake which allows the same channel which may have accumulated state to use new mutually agreed upon application packet data format(s) and associated new logic. +- Ensures exactly-once delivery of packet flow datagrams (Send, Receive, Acknowledge, Timeout) +- Ensures valid packet flow (Send => Receive => Acknowledge) XOR (Send => Timeout) + +### Identifying Counterparties + +In core IBC, the connection and channel handshakes serve to ensure the validity of counterparty clients, ensure the IBC and application versions are mutually compatible, as well as providing unique identifiers for each side to refer to the counterparty. + +Since we are removing handshakes in IBC V2, we must have a different way to provide the chain with knowledge of the counterparty. With a client, we can prove any key/value path on the counterparty. However, without knowing which identifier the counterparty uses when it sends messages to us; we cannot differentiate between messages sent from the counterparty to our chain vs messages sent from the counterparty with other chains. Most implementations will not be able to store the ICS-24 paths directly as a key in the global namespace; but will instead write to a reserved, prefixed keyspace so as not to conflict with other application state writes. Thus the counterparty information we must have includes both its identifier for our chain as well as the key prefix under which it will write the provable ICS-24 paths. + +Thus, IBC V2 will introduce a new message RegisterCounterparty that will associate the counterparty client of our chain with our client of the counterparty. Thus, if the RegisterCounterparty message is submitted to both sides correctly. Then both sides have mirrored <client,client> pairs that can be treated as identifiers for the sender and receiver chains the packet is associated with. Assuming they are correct, the client on each side is unique and provides an authenticated stream of packet data between the two chains. If the RegisterCounterparty message submits the wrong clientID, this can lead to invalid behaviour; but this is equivalent to a relayer submitting an invalid client in place of a correct client for the desired chain. In the simplest case, we can rely on out-of-band social consensus to only send on valid <client, client> pairs that represent a connection between the desired chains of the user; just as we rely on out-of-band social consensus that a given clientID and channel built on top of it is the valid, canonical identifier of our desired chain in IBC V1. + + +```typescript +interface Counterparty { + clientId: bytes + counterpartyPrefix: []bytes +} +``` + +This `Counterparty` will be keyed on the client identifier existing on our chain. Thus, both sides get access to each other's client identifier. This effectively creates a connection with unique identifiers on both sides that reference each other's consensus. Thus, the resulting `client, client` pairing in IBC V2 replaces the separate connection layer that existed in IBC V1. + +The `RegisterCounterparty` method allows for authentication that implementations may verify before storing the provided counterparty identifier. The strongest authentication possible is to have a valid clientState and consensus state of our chain in the authentication along with a proof it was stored at the claimed counterparty identifier. This is equivalent to the `validateSelfClient` logic performed in the connection handshake. +A simpler but weaker authentication would simply be to check that the `RegisterCounterparty` message is sent by the same relayer that initialized the client. This would make the client parameters completely initialized by the relayer. Thus, users must verify that the client is pointing to the correct chain and that the counterparty identifier is correct as well before using identifiers to send a packet. In practice, this is verified by social consensus. + +### IBC V2 Packet Processing + +IBC V2 will simply provide packet delivery between two chains communicating and identifying each other by on-chain light clients as specified in [ICS-02](../core/ics-002-client-semantics/README) with application packet data being routed to their specific IBC applications with packet-flow semantics as specified in [ICS-04](../core/ics-004-channel-and-packet-semantics/README). The packet clientIDs as mentioned above will tell the IBC router which chain to send the packets to and which chain a received packet came from, while the portIDs in the payload specifies which application on the router the packet should be sent to. + +Thus, once two chains have set up clients for each other with specific Identifiers, they can send IBC packets like so. + +```typescript +interface Packet { + sequence: uint64 + timeoutTimestamp: uint64 + sourceClientId: Identifier // identifier of the destination client on sender chain + destClientId: Identifier // identifier of the sender client on the destination chain + payload: []Payload +} +``` + +Since the packets are addressed **directly** with the underlying light clients, there are **no** more handshakes necessary. Instead the packet sender must be capable of providing the correct `` pair. + +Sending a packet with the wrong source client is equivalent to sending a packet with the wrong source channel. Sending a packet on a client with the wrong provided counterparty is an error and will cause the packet to be rejected. If the counterparty is set incorrectly for the new client, this is a misconfiguration in the IBC V2 setup process. Unexpected behavior may occur in this case, though it is expected that users validate the counterparty configurations on both sides are correct before sending packets using the client identifiers. This validation may be done directly or through social consensus. + +If the client and counterparty identifiers are setup correctly, then the correctness and soundness properties of IBC holds. IBC packet flow is guaranteed to succeed. If the counterparty is misconfigured, then as we will see it will be impossible for the intended destination to correctly verify the packet thus, the packet will simply time out. + +The Payload contains all the application specific information. This includes the opaque application data that the sender application wishes to send to the receiving application; it also includes the `Encoding` and `Version` that should be used to decode and process the application data. Note that this is a departure from IBC V1 where this metadata about how to process the application data was negotiated in the channel handshake. Here, each packet carries the information about how its individual data should be processed. This allows the `Version` and `Encoding` to change from packet to packet; allowing applications to upgrade asynchronously and optimistically send new packet encodings and versions to their counterparties. If the counterparty application can support receiving the new payload, it will successfully be processed; otherwise the receive will simply error and the sending application reverts state upon receiving the `ErrorAcknowledgement`. This increases the possibility for errors to occur during an application's packet processing but massively increases the flexibility of IBC applications to upgrade and evolve over time. Similarly, the portIDs on the sender and receiver application are no longer prenegotiated in the channel handshake and instead are in the payload. Thus in IBC v2; a sending application can route its packet to ANY OTHER application on the receiving application by simply specifying its portID in the payload as a receiver. It is incumbent on applications to restrict which counterparty applications it wishes to communicate with by validating the source and destination portIDs provided in the payload. Thus, the per-packet `Payload` replaces the separate channel layer that existed in IBC V1. + +For more details on the Payload structure, see [ICS-04](../core/ics-004-channel-and-packet-semantics/README). + +### Registering IBC applications on the router + +**IBC CORE** contains routers mapping reserved application portIDs to individual IBC applications as well as a mapping from clientIDs to individual IBC clients. + +```typescript +type IBCRouter struct { + apps: portID -> IBCApp + clients: clientId -> IBCClient +} +``` + +### Packet Flow + +For a detailed specification of the packet flow, please refer to [ICS-04](../core/ics-004-channel-and-packet-semantics/README). + +The packet-flow messages defined by IBC are: `SendPacket`, `ReceivePacket`, `AcknowledgePacket` and `TimeoutPacket`. `SendPacket` will most often be triggered by user-action that wants to initiate a cross-chain action (e.g. token transfer) by sending a packet from an application on the sender chain to an application on the destination chain. Every other message is the result of counterparty action, thus they must be submitted by an off-chain relayer that can submit a proof of counterparty that authenticates the message is valid. For example, the `RecvPacket` message can only be submitted if the relayer can prove that the counterparty did send a packet to our chain by submitting a proof to our on-chain client. The source chain commits the packet under the ICS-04 standardized commitment path which is constructed with `packet.sourceClientId` and `packet.sequence`. Since the `packet.sourceClientId` is a unique reference to the destination chain on the source chain, a packet commitment stored on this path is guaranteed to be a packet the source chain intends to send to the destination chain. The destination chain can verify this path using its on-chain client identified by `packet.destClientId` + +Similarly, `AcknowledgePacket` and `TimeoutPacket` are messages that get sent back to the sending chain after the an attempted packet receipt. If the packet receipt is successful, an application-specific acknowledgement will be written to the ICS-04 standardized acknowledgement path under the `packet.destClientId` and `packet.sequence`. The sending chain can verify that the relayer-provided acknowledgment was committed to by the receiving chain by verifying this path using the on-chain client identified by `packet.sourceClientId`. Since the `packet.destClientId` is a unique reference to the sending chain on the destination chain and the `sequence` is unique in the stream of packets from source chain to destination; we can be guaranteed that the acknowledgement was written for the packet we previously sent with the provided `sourceClientId` and `sequence`. This acknowledgement is then given to the sending application to perform appropriate application logic for the given acknowledgement. + +The `TimeoutPacket` is called if the packet receipt is unsuccessful. All compliant implementations must write a sentinel non-empty value into the standardized ICS-04 receipt path if it successfully receives a packet. This receipt path is constructed using the `packet.destClientId` and `packet.sequence`. Thus, if the value does not exist after the packet timeout has been passed, we can be guaranteed that the packet has timed out. The sending chain verifies a relayer-provided `NonMembership` proof for the receipt path of the given packet, if it succeeds then the timeout is verified and the timeout logic for the sending application is executed. Note the nonmembership proof MUST be verified against a consensus state that is executed past the timeout timestamp of the packet, and packet receiving MUST fail on the destination after the timeout has elapsed. This ensures that a packet cannot be timed out on the source chain and received on the destination simultaneously. + +Thus, the packet handler implements the handlers for these messages by constructing the necessary path and value to authenticate the message as specified in [ICS-04](../core/ics-004-channel-and-packet-semantics/README); it then routes the verification of the membership/nonmembership proof to the relevant [ICS-02](../core/ics-002-client-semantics/README) client as specified in the packet. If the IBC TAO checks succeed and the client verification succeeds; then the packet message is authenticated and the application data in the payload can be processed by the application as trusted data. The packet sequence ensures that the stream of packets from a source chain to destination chain are all uniquely identified and prevents replay attacks. More detailed specification of the IBC TAO checks and packet handler behaviour can be found in [ICS-04](../core/ics-004-channel-and-packet-semantics/README). + +### Correctness + +Claim: If the clients are setup correctly, then a chain can always verify packet flow messages sent by a valid counterparty. + +If the clients are correct, then they can verify any key/value membership proof as well as a key non-membership proof. + +All packet flow message (SendPacket, RecvPacket, and TimeoutPacket) are sent with the full packet. The packet contains both sender and receiver identifiers. Thus on packet flow messages sent to the receiver (RecvPacket), we use the receiver identifier in the packet to retrieve our local client and the source identifier to determine which path the sender stored the packet under. We can thus use our retrieved client to verify a key/value membership proof to validate that the packet was sent by the counterparty. + +Similarly, for packet flow messages sent to the sender (AcknowledgePacket, TimeoutPacket); the packet is provided again. This time, we use the sender identifier to retrieve the local client and the destination identifier to determine the key path that the receiver must have written to when it received the packet. We can thus use our retrieved client to verify a key/value membership proof to validate that the packet was sent by the counterparty. In the case of timeout, if the packet receipt wasn't written to the receipt path determined by the destination identifier this can be verified by our retrieved client using the key nonmembership proof. + +### Soundness + +Claim: If the clients are setup correctly, then a chain cannot mistake a packet flow message intended for a different chain as a valid message from a valid counterparty. + +We must note that client identifiers are unique to each chain but are not globally unique. Let us first consider a user that correctly specifies the source and destination identifiers in the packet. + +We wish to ensure that well-formed packets (i.e. packets with correctly setup client ids) cannot have packet flow messages succeed on third-party chains. Ill-formed packets (i.e. packets with invalid client ids) may in some cases complete in invalid states; however we must ensure that any completed state from these packets cannot mix with the state of other valid packets. + +We are guaranteed that the source identifier is unique on the source chain, the destination identifier is unique on the destination chain. Additionally, the destination identifier points to a valid client of the source chain, and the source identifier points to a valid client of the destination chain. + +Suppose the RecvPacket is sent to a chain other than the one identified by the sourceClient on the source chain. + +In the packet flow messages sent to the receiver (RecvPacket), the packet send is verified using the client on the destination chain (retrieved using destination identifier) with the packet commitment path derived by the source identifier. This verification check can only pass if the chain identified by the destination client committed the packet we received under the source client identifier. This is only possible if the destination client is pointing to the original source chain, or if it is pointing to a different chain that committed the exact same packet. Pointing to the original source chain would mean we sent the packet to the correct . Since the sender only sends packets intended for the destination chain by setting to a unique source identifier, we can be sure the packet was indeed intended for us. Since our client on the receiver is also correctly pointing to the sender chain, we are verifying the proof against a specific consensus algorithm that we assume to be honest. If the packet is committed to the wrong key path, then we will not accept the packet. Similarly, if the packet is committed by the wrong chain then we will not be able to verify correctly. diff --git a/ibc/next/spec/IBC_V2/core/ics-002-client-semantics/README.mdx b/ibc/next/spec/IBC_V2/core/ics-002-client-semantics/README.mdx new file mode 100644 index 00000000..0f0f6b6a --- /dev/null +++ b/ibc/next/spec/IBC_V2/core/ics-002-client-semantics/README.mdx @@ -0,0 +1,519 @@ +--- +ics: 2 +title: Client Semantics +stage: draft +category: IBC/TAO +kind: interface +requires: [24] +required_by: [4] +version_compatibility: + - ibc-go v10.0.0 +authors: + - name: Juwoon Yun + email: joon@tendermint.com + - name: Christopher Goes + email: cwgoes@tendermint.com + - name: Aditya Sripal + email: aditya@interchain.io +created: 2019-02-25 +modified: 2024-08-22 +--- + +## Synopsis + +The IBC protocol provides secure packet flow between applications on different ledgers by verifying the packet messages using clients of the counterparty state machines. While ICS-4 defines the core packet flow logic between two chains and the provable commitments they must make in order to communicate, this standard ICS-2 specifies **how** a chain verifies the IBC provable commitments of the counterparty which is crucial to securely receive and process a packet flow message arriving from the counterparty. + +This standard focuses on how to keep track of the counterparty consensus and verify the state machine; it also specifies the properties that consensus algorithms of state machines implementing the inter-blockchain +communication (IBC) protocol are required to satisfy. +These properties are necessary for efficient and safe verification in the higher-level protocol abstractions. +The algorithm utilised in IBC to verify the state updates of a remote state machine is referred to as a *validity predicate*. +Pairing a validity predicate with a trusted state (i.e., a state that the verifier assumes to be correct), +implements the functionality of a *light client* (often shortened to *client*) for a remote state machine on the host state machine. +In addition to state update verification, every light client is able to detect consensus misbehaviours through a *misbehaviour predicate*. + +Beyond the properties described in this specification, IBC does not impose any requirements on +the internal operation of the state machines and their consensus algorithms. +A state machine may consist of a single process signing operations with a private key (the so-called "solo machine"), a quorum of processes signing in unison, +many processes operating a Byzantine fault-tolerant consensus algorithm (e.g., Tendermint), or other configurations yet to be invented +— from the perspective of IBC, a state machine is defined entirely by its light client validation and misbehaviour detection logic. + +This standard also specifies how the light client's functionality is registered and how its data is stored and updated by the IBC protocol. +The stored client instances can be introspected by a third party actor, +such as a user inspecting the state of the state machine and deciding whether or not to send an IBC packet. + +### Motivation + +The IBC protocol needs to be able to verify updates to the state of another state machine (i.e., the *remote state machine*). +This entails accepting *only* the state updates that were agreed upon by the remote state machine's consensus algorithm. +A light client of the remote state machine is the algorithm that enables the actor to verify state updates of that state machine. +Note that light clients will generally not include validation of the entire state transition logic +(as that would be equivalent to simply executing the other state machine), but may +elect to validate parts of state transitions in particular cases. +This standard formalises the light client model and requirements. +As a result, the IBC protocol can easily be integrated with new state machines running new consensus algorithms, +as long as the necessary light client algorithms fulfilling the listed requirements are provided. + +The IBC protocol can be used to interact with probabilistic-finality consensus algorithms. +In such cases, different validity predicates may be required by different applications. For probabilistic-finality consensus, a validity predicate is defined by a finality threshold (e.g., the threshold defines how many block needs to be on top of a block in order to consider it finalized). +As a result, clients could act as *thresholding views* of other clients: +One *write-only* client could be used to store state updates (without the ability to verify them), +while many *read-only* clients with different finality thresholds (confirmation depths after which +state updates are considered final) are used to verify state updates. + +Client interfaces should also be constructed so that custom validation logic can be provided safely +to define a custom client at runtime, as long as the underlying state machine can provide an +appropriate gas metering mechanism to charge for compute and storage. On a host state machine +which supports WASM execution, for example, the validity predicate and misbehaviour predicate +could be provided as executable WASM functions when the client instance is created. + +### Definitions + +- `Consensus` is a state update generating algorithm. It takes the previous state of a state machine together + with a set of messages (i.e., state machine transactions) and generates a valid state update of the state machine. + Every state machine MUST have a `Consensus` that generates a unique, ordered list of state updates + starting from a genesis state. + + This specification expects that the state updates generated by `Consensus` + satisfy the following properties: + - Every state update MUST NOT have more than one direct successor in the list of state updates. + In other words, the state machine MUST guarantee *finality* and *safety*. + - Every state update MUST eventually have a successor in the list of state updates. + In other words, the state machine MUST guarantee *liveness*. + - Every state update MUST be valid (i.e., valid state transitions). + In other words, `Consensus` MUST be *honest*, + e.g., in the case `Consensus` is a Byzantine fault-tolerant consensus algorithm, + such as Tendermint, less than a third of block producers MAY be Byzantine. + + Unless the state machine satisfies all of the above properties, the IBC protocol +may not work as intended, e.g., users' assets might be stolen. Note that specific client +types may require additional properties. + +- `Height` specifies the order of the state updates of a state machine, e.g., a sequence number. + This entails that each state update is mapped to a `Height`. + +- `ClientMessage` is an arbitrary message defined by the client type that relayers can submit in order to update the client. + The ClientMessage may be intended as a regular update which may add new consensus state for proof verification, or it may contain + misbehaviour which should freeze the client. + +- `ValidityPredicate` is a function that validates a ClientMessage sent by a relayer in order to update the client. + Using the `ValidityPredicate` SHOULD be more computationally efficient than executing `Consensus`. + +```typescript +type ValidityPredicate = (clientState: bytes, trustedConsensusState: bytes, trustedHeight: Number) => (newConsensusState: bytes, newHeight: Number, err: Error) +``` + +- `ConsensusState` is the *trusted view* of the state of a state machine at a particular `Height`. + It MUST contain sufficient information to enable the `ValidityPredicate` to validate future state updates, + which can then be used to generate new `ConsensusState`s. + +- `ClientState` is the state of a client. It MUST expose an interface to higher-level protocol abstractions, + e.g., functions to verify proofs of the existence of particular values at particular paths at particular `Height`s. + +- `MisbehaviourPredicate` is a function that checks whether the rules of `Consensus` were broken, + in which case the client MUST be *frozen*, i.e., no subsequent `ConsensusState`s can be generated. + Verification against the client after it is frozen will also fail. + +```typescript +type MisbehaviourPredicate = (clientState: bytes, trustedConsensusState: bytes, trustedHeight: Number, misbehaviour: bytes) => bool +``` + +- `Misbehaviour` is the proof needed by the `MisbehaviourPredicate` to determine whether + a violation of the consensus protocol occurred. For example, in the case the state machine + is a blockchain, a `Misbehaviour` might consist of two signed block headers with + different `ConsensusState` for the same `Height`. + +### Desired Properties + +Light clients MUST provide state verification functions that provide a secure way +to verify the state of the remote state machines using the existing `ConsensusState`s. +These state verification functions enable higher-level protocol abstractions to +verify sub-components of the state of the remote state machines. + +`ValidityPredicate`s MUST reflect the behaviour of the remote state machine and its `Consensus`, i.e., +`ValidityPredicate`s accept *only* state updates that contain state updates generated by +the `Consensus` of the remote state machine. + +In case of misbehavior, the behaviour of the `ValidityPredicate` might differ from the behaviour of +the remote state machine and its `Consensus` (since clients do not execute the `Consensus` of the +remote state machine). In this case, a `Misbehaviour` SHOULD be submitted to the host state machine, +which would result in the client being frozen. Once the client is frozen, a recovery mechanism to address +the situation must occur before client processing can presume. This recovery mechanism is out-of-scope +of the IBC protocol as the specific recovery needed is highly case-dependent. + +## Technical Specification + +This specification outlines what each *client type* must define. A client type is a set of definitions +of the data structures, initialisation logic, validity predicate, and misbehaviour predicate required +to operate a light client. State machines implementing the IBC protocol can support any number of client +types, and each client type can be instantiated with different initial consensus states in order to track +different consensus instances. + +Specific client types and their specifications are defined in the light clients section of this repository. + +### Data Structures + +#### `Height` + +`Height` is an opaque data structure defined by a client type. +It must form a partially ordered set & provide operations for comparison. + +```typescript +type Height +``` + +```typescript +enum Ord { + LT + EQ + GT +} + +type compare = (h1: Height, h2: Height) => Ord +``` + +A height is either `LT` (less than), `EQ` (equal to), or `GT` (greater than) another height. + +`>=`, `>`, `===`, `<`, `<=` are defined through the rest of this specification as aliases to `compare`. + +There must also be a zero-element for a height type, referred to as `0`, which is less than all non-zero heights. + +#### `ConsensusState` + +`ConsensusState` is an opaque data structure defined by a client type, used by the validity predicate to +verify new commits & state roots. Likely the structure will contain the last commit produced by +the consensus process, including signatures and validator set metadata. + +`ConsensusState` MUST be generated from an instance of `Consensus`, which assigns unique heights +for each `ConsensusState` (such that each height has exactly one associated consensus state). +There MUST NOT be two valid `ConensusState`s for the same height. +Such an event is called an "equivocation" and MUST be classified +as misbehaviour. Should one occur, a proof should be generated and submitted so that the client can be frozen +and previous state roots invalidated as necessary. + +```typescript +type ConsensusState = bytes +``` + +The `ConsensusState` MUST define a `getTimestamp()` method which returns the timestamp **in seconds** associated with that consensus state. +This timestamp MUST be the timestamp used in the counterparty state machine and agreed to by `Consensus`. + +```typescript +type getTimestamp = ConsensusState => uint64 +``` + +#### `ClientState` + +`ClientState` is an opaque data structure defined by a client type. +It may keep arbitrary internal state to track verified roots and past misbehaviours. + +Light clients are representation-opaque — different consensus algorithms can define different light client update algorithms — +but they must expose this common set of query functions to the IBC handler. + +```typescript +type ClientState = bytes +``` + +Client types MUST define a method to initialise a client state with the provided client identifier, client state and consensus state, writing to internal state as appropriate. + +```typescript +type initialise = (identifier: Identifier, clientState: ClientState, consensusState: ConsensusState) => Void +``` + +Client types MUST define a method to fetch the current height (height of the most recent validated state update). + +```typescript +type latestClientHeight = ( + clientState: ClientState) + => Height +``` + +Client types MUST define a method on the client state to fetch the timestamp at a given height + +```typescript +type getTimestampAtHeight = ( + clientState: ClientState, + height: Height +) => uint64 +``` + +#### `ClientMessage` + +A `ClientMessage` is an opaque data structure defined by a client type which provides information to update the client. +`ClientMessage`s can be submitted to an associated client to add new `ConsensusState`(s) and/or update the `ClientState`. They likely contain a height, a proof, a commitment root, and possibly updates to the validity predicate. + +```typescript +type ClientMessage = bytes +``` + +#### `CommitmentProof` + +`CommitmentProof` is an opaque data structure defined by the client type. + +```typescript +type CommitmentProof = bytes +``` + +It is utilised to verify presence or absence of a particular key/value pair in state +at a particular finalised height (necessarily associated with a particular commitment root). + +### State verification + +Client types must define functions to authenticate internal state of the state machine which the client tracks. +Internal implementation details may differ (for example, a loopback client could simply read directly from the state and require no proofs). + +`verifyMembership` is a generic proof verification method which verifies a proof of the existence of a value at a given `CommitmentPath` at the specified height. It MUST return an error if the verification is not successful. +The caller is expected to construct the full `CommitmentPath` from a `CommitmentPrefix` and a standardized path (as defined in [ICS 4](../ics-004-packet-semantics/PACKET)). + +```typescript +type verifyMembership = ( + clientState: ClientState, + height: Height, + proof: CommitmentProof, + path: CommitmentPath, + value: bytes) + => Error +``` + +`verifyNonMembership` is a generic proof verification method which verifies a proof of absence of a given `CommitmentPath` at the specified height. It MUST return an error if the verification is not successful. +The caller is expected to construct the full `CommitmentPath` from a `CommitmentPrefix` and a standardized path (as defined in [ICS 24](../ics-024-host-requirements/README#path-space)). + +Since the verification method is designed to give complete control to client implementations, clients can support chains that do not provide absence proofs by verifying the existence of a non-empty sentinel `ABSENCE` value. Thus in these special cases, the proof provided will be an Existence proof, and the client will verify that the `ABSENCE` value is stored under the given path for the given height. + +```typescript +type verifyNonMembership = ( + clientState: ClientState, + height: Height, + proof: CommitmentProof, + path: CommitmentPath) + => Error +``` + +#### Implementation strategies + +##### Loopback + +A loopback client of a local state machine merely reads from the local state, to which it must have access. + +##### Simple signatures + +A client of a solo state machine with a known public key checks signatures on messages sent by that local state machine, +which are provided as the `Proof` parameter. The `height` parameter can be used as a replay protection nonce. + +Multi-signature or threshold signature schemes can also be used in such a fashion. + +##### Proxy clients + +Proxy clients verify another (proxy) state machine's verification of the target state machine, by including in the +proof first a proof of the client state on the proxy state machine, and then a secondary proof of the sub-state of +the target state machine with respect to the client state on the proxy state machine. This allows the proxy client to +avoid storing and tracking the consensus state of the target state machine itself, at the cost of adding +security assumptions of proxy state machine correctness. + +##### Merklized state trees + +For clients of state machines with Merklized state trees, these functions can be implemented as MerkleTree Existence and NonExistence proofs. Client implementations may choose to implement these methods for the specific tree used by the counterparty chain or they can use the tree-generic [ICS-23](https://github.com/cosmos/ics23) `verifyMembership` or `verifyNonMembership` methods, using a verified Merkle +root stored in the `ClientState`, to verify presence or absence of particular key/value pairs in state at particular heights for any ICS-23 compliant tree given a ProofSpec that describes how the tree is constructed. In this case, the ICS-23 `ProofSpec` MUST be provided to the client on initialization. + +### Sub-protocols + +IBC handlers MUST implement the functions defined below. + +#### Identifier validation + +Clients are stored under a unique `Identifier` prefix. +This ICS does not require that client identifiers be generated in a particular manner, only that they be unique. +However, it is possible to restrict the space of `Identifier`s if required. +The validation function `validateClientIdentifier` MAY be provided. + +```typescript +type validateClientIdentifier = (id: Identifier) => boolean +``` + +If not provided, the default `validateClientIdentifier` will always return `true`. + +##### Utilising past roots + +To avoid race conditions between client updates (which change the state root) and proof-carrying +transactions in handshakes or packet receipt, many IBC handler functions allow the caller to specify +a particular past root to reference, which is looked up by height. IBC handler functions which do this +must ensure that they also perform any requisite checks on the height passed in by the caller to ensure +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. + +CreateClient Inputs: + +`clientType: string`: This is the client-type that references a particular light client implementation on the chain. The `CreateClient` message will create a new instance of the given client-type. +`ClientState: bytes`: This is the opaque client state as defined for the given client type. It will contain any parameters needed for verifying client updates and proof verification against a `ConsensusState`. The `ClientState` parameterizes the security model as implemented by the client type. +`ConsensusState: bytes`: This is the opaque consensus state as defined for the given client type. It is the initial consensus state provided and MUST be capable of being used by the `ValidityPredicate` to add new `ConsensusState`s to the client. The initial `ConsensusState` MAY also be used for proof verification but it is not necessary. +`Height: Number`: This is the height that is associated with the initial consensus state. + +CreateClient Preconditions: + +- The provided `clientType` is supported by the chain and can be routed to by the IBC handler. + +CreateClient PostConditions: + +- A unique identifier `clientId` is generated for the client +- The provided `ClientState` is persisted to state and retrievable given the `clientId`. +- The provided `ConsensusState` is persisted to state and retrievable given the `clientId` and `height`. + +CreateClient ErrorConditions: + +- The provided `ClientState` is invalid given the client type. +- The provided `ConsensusState` is invalid given the client type. +- The `Height` is not a positive number. + +#### RegisterCounterparty + +IBC Version 2 introduces a `registerCounterparty` procedure. Calling `registerCounterparty` with the clientId will register the counterparty clientId +that the counterparty will use to write packet messages intended for our chain. All ICS24 provable paths to our chain will be keyed on the counterparty clientId, so each client must be aware of the counterparty's identifier in order to construct the path for key verification and ensure there is an authenticated stream of packet data between the clients that do not get written to by other clients. +The `registerCounterparty` also includes the `CommitmentPrefix` to use for the counterparty chain. Most chains will not store the ICS24 directly under the root of a MerkleTree and will instead store the standardized paths under a custom prefix, thus the counterparty client must be given this information to verify proofs correctly. The `CommitmentPrefix` is defined as an array of byte arrays to support nested Merkle trees. In this case, each element of the outer array is a key for each tree in the nested structure ordered from the top-most tree to the lowest level tree. In this case, the ICS24 path is appended to the key of the lowest-level tree (i.e. the last element of the commitment prefix) in order to get the full `CommitmentPath` for proof verification. + +RegisterCounterparty Inputs: + +`clientId: bytes`: The clientId on the executing chain. +`counterpartyClientId: bytes`: The identifier of the client used by the counterparty chain to verify the executing chain. +`counterpartyCommitmentPrefix: []bytes`: The prefix used by the counterparty chain. + +RegisterCounterparty Preconditions: + +- A client has already been created for the `clientId` + +RegisterCounterparty Postconditions: + +- The `counterpartyClientId` is retrievable given the `clientId`. +- The `counterpartyCommitmentPrefix` is retrievable given the `clientId`. + +RegisterCounterparty ErrorConditions: + +- There does not exist a client for the given `clientId` +- `RegisterCounterparty` has already been called for the given `clientId` + +NOTE: Once the clients and counterparties have been registered on both sides, the connection between the clients is established and packet flow between the clients may commence. Users are expected to verify that the clients and counterparties are set correctly before using the connection to send packets. They may do this directly themselves or through social consensus. +NOTE: `RegisterCounterparty` is setting information that will be crucial for proper proof verification of IBC messages using our client. Thus, it must be authenticated properly. The `RegisterCounterparty` message can be permissionless in which case the fields must be authenticated against the counterparty chain using the client which may prove difficult and cumbersome. It is RECOMMENDED to simply ensure that the client creator address is the same as the one that registers the counterparty. Once the client and counterparty are set by the same creator, users can decide if the configuration is secure out-of-band. + +#### Update + +Updating a client is done by submitting a new `ClientMessage`. The `Identifier` is used to point to the +stored `ClientState` that the logic will update. When a new `ClientMessage` is verified using the `ValidityPredicate` with +the stored `ClientState` and a previously stored `ConsensusState`, the client MUST then add a new `ConsensusState` with a new `Height`. + +If a client can no longer be updated (if, for example, the trusting period has passed), +then new packet flow will not be able to be processed. Manual intervention must take place to +reset the client state or migrate the client. This +cannot safely be done completely automatically, but chains implementing IBC could elect +to allow governance mechanisms to perform these actions +(perhaps even per-client/connection/channel in a multi-sig or contract). + +UpdateClient Inputs: + +`clientId: bytes`: The identifier of the client being updated. +`clientMessage: bytes`: The opaque clientMessage to update the client as defined by the given `clientType`. It MUST include the `trustedHeight` we wish to update from. This `trustedHeight` will be used to retrieve a trusted ConsensusState which we will use to update to a new consensus state using the `ValidityPredicate`. + +UpdateClient Preconditions: + +- A client has already been created for the `clientId` + +UpdateClient Postconditions: + +- A new `ConsensusState` is added to the client and persisted with a new `Height` +- Implementations MAY automatically detect misbehaviour in `UpdateClient` if the update itself is proof of misbehaviour (e.g. There is already a different `ConsensusState` for the given height, or time monotonicity is broken). It is recommended to automatically freeze the client in this case to avoid having to send a redundant `submitMisbehaviour` message. + +UpdateClient ErrorConditions: + +- The trusted `ConsensusState` referenced in the `ClientMessage` does not exist in state +- `ValidityPredicate(clientState, trustedConsensusState, trustedHeight)` returns an error + +#### Misbehaviour + +If `Consensus` of the counterparty chain is violated, then the relayer can submit proof of this as misbehaviour. Once the client is frozen, no updates may take place and all proof verification will fail. The client may be unfrozen by an out-of-band protocol once trust in the counterparty `Consensus` is restored and any invalid state caused by the break in `Consensus` is reverted on the executing chain. + +SubmitMisbehaviour Inputs: +`clientId: bytes`: The identifier of the client being frozen. +`clientMessage: bytes`: The opaque clientMessage to freeze the client as defined by the given `clientType`. It MUST include the `trustedHeight` we wish to verify misbehaviour from. This `trustedHeight` will be used to retrieve a trusted ConsensusState which we will use to freeze the client given the `MisbehaviourPredicate`. It MUST also include the misbehaviour being submitted. + +SubmitMisbehaviour Preconditions: + +- A client has already been created for the `clientId`. + +SubmitMisbehaviour Postconditions: + +- The client is frozen, update and proof verification will fail until client is unfrozen again. + +SubmitMisbehaviour ErrorConditions: + +- The trusted `ConsensusState` referenced in the `ClientMessage` does not exist in state. +- `MisbehaviourPredicate(clientState, trustedConsensusState, trustedHeight, misbehaviour)` returns `false`. + +### VerifyMembership and VerifyNonmembership + +The IBC core packet handler uses the consensus states created in `UpdateClient` to verify ICS-4 standardized paths to authenticate packet messages. In order to do this, the IBC packet handler constructs the expected key/value for the given packet flow message and sends the expected path and value to the client along with the relayer-provided proof to the client for verification. Note that the proof is relayer provided, but the path and value are constructed by the IBC packet handler for the given packet. Thus, the relayer cannot forge proofs for packets that did not get sent. IBC Packet handler must also have the ability to prove nonmembership of a given path in order to enable timeout processing. Thus, clients must expose the following `verifyMembership` and `verifyNonMembership` methods: + +```typescript +type verifyMembership = (ClientState, Height, CommitmentProof, Path, Value) => boolean +``` + +```typescript +type verifyNonMembership = (ClientState, Height, CommitmentProof, Path) => boolean +``` + +ProofVerification Inputs: + +- `clientId: bytes`: The identifier of the client that will verify the proof. +- `Height: Number`: The height for the consensus state that the proof will be verified against. +- `Path: CommitmentPath`: The path of the key being proven. In the IBC protocol, this will be an ICS24 standardized path prefixed by the `CommitmentPrefix` registered on the counterparty. The `Path` MUST be constructed by the IBC handler given the IBC message, it MUST NOT be provided by the relayer as the relayer is untrusted. +- `Value: Optional`: The value being proven. If it is non-empty this is a membership proof. If the value is nil, this is a non-membership proof. + +ProofVerification Preconditions: + +- A client has already been created for the `clientId`. +- A `ConsensusState` is stored for the given `Height`. + +ProofVerification Postconditions: + +- Proof verification should be stateless in most cases. In the case that the proof verification is a signature check, we may wish to increment a nonce to prevent replay attacks. + +ProofVerification Errorconditions: + +- `CommitmentProof` does not successfully verify with the provided `CommitmentPath` and `Value` with the retrieved `ConsensusState` for the provided `Height`. + +### Properties & Invariants + +- Client identifiers are immutable & first-come-first-serve. Clients cannot be deleted (allowing deletion would potentially allow future replay of past packets if identifiers were re-used). + +## Backwards Compatibility + +Not applicable. + +## Forwards Compatibility + +New client types can be added by IBC implementations at-will as long as they conform to this interface. + +## Example Implementations + +Please see the ibc-go implementations of light clients for examples of how to implement your own: (https://github.com/cosmos/ibc-go/blob/main/modules/light-clients). + +## History + +Mar 5, 2019 - Initial draft finished and submitted as a PR + +May 29, 2019 - Various revisions, notably multiple commitment-roots + +Aug 15, 2019 - Major rework for clarity around client interface + +Jan 13, 2020 - Revisions for client type separation & path alterations + +Jan 26, 2020 - Addition of query interface + +Jul 27, 2022 - Addition of `verifyClientState` function, and move `ClientState` to the `provableStore` + +August 4, 2022 - Changes to ClientState interface and associated handler to align with changes in 02-client-refactor ADR: (https://github.com/cosmos/ibc-go/pull/1871) + +August 22, 2024 - [Changes for IBC/TAO V2](https://github.com/cosmos/ibc/pull/1147) + +## Copyright + +All content herein is licensed under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0). diff --git a/ibc/next/spec/IBC_V2/core/ics-004-packet-semantics/PACKET.mdx b/ibc/next/spec/IBC_V2/core/ics-004-packet-semantics/PACKET.mdx new file mode 100644 index 00000000..bd9c18be --- /dev/null +++ b/ibc/next/spec/IBC_V2/core/ics-004-packet-semantics/PACKET.mdx @@ -0,0 +1,172 @@ +--- +title: "Packet Structure and Provable Commitment Specification" +--- + +## Packet V2 Structure + +The IBC packet sends application data from a source chain to a destination chain with a timeout that specifies when the packet is no longer valid. The packet will be committed to by the source chain as specified in the ICS-24 specification. The receiver chain will then verify the packet commitment under the ICS-24 specified packet commitment path. If the proof succeeds, the IBC handler sends the application data(s) to the relevant application(s). + +```typescript +interface Packet { + // identifier for the destination-chain client existing on source chain + sourceClientId: bytes, + // identifier for the source-chain client existing on destination chain + destClientId: bytes, + // the sequence uniquely identifies this packet + // in the stream of packets from source to dest chain + sequence: uint64, + // the timeout is the timestamp in seconds on the destination chain + // at which point the packet is no longer valid. + // It cannot be received on the destination chain and can + // be timed out on the source chain + timeout: uint64, + // the data includes the messages that are intended + // to be sent to application(s) on the destination chain + // from application(s) on the source chain + // IBC core handlers will route the payload to the desired + // application using the port identifiers but the rest of the + // payload will be processed by the application + data: [Payload] +} + +interface Payload { + // sourcePort identifies the sending application on the source chain + sourcePort: bytes, + // destPort identifies the receiving application on the dest chain + destPort: bytes, + // version identifies the version that sending application + // expects destination chain to use in processing the message + // if dest chain does not support the version, the payload must + // be rejected with an error acknowledgement + 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 + // if the encoding is not supported, receiving application + // must be rejected with an error acknowledgement. + // the encoding string MUST be in MIME format + encoding: string, + // appData is the opaque content sent from the source application + // to the dest application. It will be decoded and interpreted + // as specified by the version and encoding fields + appData: bytes, +} +``` + +The source and destination client identifiers at the top-level of the packet identify the chains communicating. The `sourceClientId` identifier **must** be unique on the source chain and is a pointer to the destination chain client on the source chain. The `destClientId` identifier **must** be a unique identifier on the destination chain and is a pointer to the source chain client on the destination chain. The sequence is a monotonically incrementing nonce to uniquely identify packets sent between the source and destination chain. + +The timeout is the UNIX timestamp in seconds that must be passed on the **destination** chain before the packet is invalid and no longer capable of being received. Note that the timeout timestamp is assessed against the destination chain's clock which may drift relative to the clocks of the sender chain or a third party observer. If a packet is received on the destination chain after the timeout timestamp has passed relative to the destination chain's clock; the packet must be rejected so that it can be safely timed out and reverted by the sender chain. + +In version 2 of the IBC specification, implementations **MAY** support multiple application data within the same packet. This can be represented by a list of payloads. Implementations may choose to only support a single payload per packet, in which case they can just reject incoming packets sent with multiple payloads. + +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: + +```typescript +func packetCommitmentPath(packet: Packet): bytes { + return packet.sourceClientId + byte(0x01) + bigEndian(packet.sequence) +} +``` + +```typescript +// commitPayload hashes all the fields of the packet data to create a standard size +// preimage before committing it in the packet. +func commitPayload(payload: Payload): bytes { + buffer = sha256.Hash(payload.sourcePort) + buffer = append(sha256.Hash(payload.destPort)) + buffer = append(sha256.Hash(payload.version)) + buffer = append(sha256.Hash(payload.encoding)) + buffer = append(sha256.Hash(payload.appData)) + return sha256.Hash(buffer) +} + +// commitV2Packet commits to all fields in the packet +// by hashing each individual field and then hashing these fields together +// Note: SourceClient and the sequence are omitted since they will be included in the key +// Every other field of the packet is committed to in the packet which will be stored in the +// packet commitment value +// The final preimage will be prepended by the byte 0x02 before hashing in order to clearly define the protocol version +// and allow for future upgradability +func commitV2Packet(packet: Packet) { + timeoutBytes = LittleEndian(packet.timeout) + var appBytes: bytes + for p in packet.payload { + appBytes = append(appBytes, commitPayload(p)) + } + buffer = sha256.Hash(packet.destClient) + buffer = append(buffer, sha256.hash(timeoutBytes)) + buffer = append(buffer, sha256.hash(appBytes)) + buffer = append([]byte{0x02}, buffer) + return sha256.Hash(buffer) +} +``` + +## Acknowledgement V2 + +The acknowledgement in the version 2 specification is also modified to support multiple payloads in the packet that will each go to separate applications that can write their own acknowledgements. Each acknowledgment will be contained within the final packet acknowledgment in the same order that they were received in the original packet. Thus if a packet contains payloads for modules `A` and `B` in that order; the receiver will write an acknowledgment with the app acknowledgements `A` and `B` in the same order. + +The acknowledgement which is itself a list of app acknowledgement bytes must be committed to by hashing each individual acknowledgement and concatenating them together and hashing the result. This ensures that all compliant implementations reach the same acknowledgment commitment and that two different acknowledgements never create the same commitment. + +An application may not need to return an acknowledgment. In this case, it may return a sentinel acknowledgement value `SENTINEL_ACKNOWLEDGMENT` which will be the single byte in the byte array: `bytes(0x01)`. In this case, the IBC `acknowledgePacket` handler will still do the core IBC acknowledgment logic but it will not call the application's acknowledgePacket callback. + +```typescript +interface Acknowledgement { + // Each app in the payload will have an acknowledgment in this list in the same order + // that they were received in the payload + // If an app does not need to send an acknowledgement, there must be a SENTINEL_ACKNOWLEDGEMENT + // in its place + // The app acknowledgement must be encoded in the same manner specified in the payload it received + // and must be created and processed in the manner expected by the version specified in the payload. + appAcknowledgement: [bytes] +} +``` + +All acknowledgements must be committed to and stored under the standardized acknowledgment path. Note that since each acknowledgement is associated with a given received packet, the acnowledgement path is constructed using the packet `destClientId` and its `sequence` to generate a unique key for the acknowledgement. + +```typescript +func acknowledgementPath(packet: Packet) { + return packet.destClientId + byte(0x02) + bigEndian(packet.Sequence) +} +``` + +```typescript +// commitV2Acknowledgement hashes each app acknowledgment and hashes them together +// the final preimage will be prepended with the byte 0x02 before hashing in order to clearly define the protocol version +// and allow for future upgradability +func commitV2Acknowledgment(ack: Acknowledgement) { + var buffer: bytes + for appAck in ack.appAcknowledgement { + buffer = append(buffer, sha256.Hash(appAck)) + } + buffer = append([]byte{0x02}, buffer) + return sha256.Hash(buffer) +} +``` + +## Packet Receipt V2 + +A packet receipt will only tell the sending chain that the counterparty has successfully received the packet. Thus we just need a provable boolean flag uniquely associated with the sent packet. Thus, the receiver chain stores the packet receipt keyed on the destination identifier and the sequence to uniquely identify the packet. + +For chains that support nonexistence proofs of their own state, they can simply write a `SENTINEL_RECEIPT_VALUE` under the receipt path. This `SENTINEL_RECEIPT_PATH` can be any non-nil value so it is recommended to write a single byte. The receipt path is standardized as below. Similar to the acknowledgement, each receipt is associated with a given received packet the receipt path is constructed using the packet `destClientId` and its `sequence` to generate a unique key for the receipt. + +```typescript +func receiptPath(packet: Packet) { + return packet.destClientId + byte(0x03) + bigEndian(packet.Sequence) +} +``` + +## Provable Path-space + +IBC/TAO implementations MUST implement the following paths for the `provableStore` in the exact format specified. This is because counterparty IBC/TAO implementations will construct the paths according to this specification and send it to the light client to verify the IBC specified value stored under the IBC specified path. The `provableStore` is specified in [ICS24 Host Requirements](../ics-024-host-requirements/README) + +Future paths may be used in future versions of the protocol, so the entire key-space in the provable store MUST be reserved for the IBC handler. + +| Value | Path format | +| -------------------------- | ---------------------------------------------- | +| Packet Commitment | {sourceClientId}0x1{bigEndianUint64Sequence} | +| Packet Receipt | {destClientId}0x2{bigEndianUint64Sequence} | +| Acknowledgement Commitment | {destClientId}0x3{bigEndianUint64Sequence} | + +Note that the IBC protocol ensures that the packet `(sourceClientId, sequence)` tuple uniquely identifies a packet on the sending chain, and the `(destClientId, sequence)` tuple uniquely identifies a packet on the receiving chain. This property along with the byte separator between the client identifier and sequence in the standardized paths ensures that commitments, receipts, and acknowledgements are each written to different paths for the same packet. Thus, so long as the host requirements specified in ICS24 are respected; a provable key written to state by the IBC handler for a given packet will never be overwritten with a different value. This ensures secure and correct communication between chains in the IBC ecosystem. diff --git a/ibc/next/spec/IBC_V2/core/ics-004-packet-semantics/PACKET_HANDLER.mdx b/ibc/next/spec/IBC_V2/core/ics-004-packet-semantics/PACKET_HANDLER.mdx new file mode 100644 index 00000000..6df069dd --- /dev/null +++ b/ibc/next/spec/IBC_V2/core/ics-004-packet-semantics/PACKET_HANDLER.mdx @@ -0,0 +1,208 @@ +--- +title: "IBC Packet Handler" +--- + +The packet handler specification defines the semantics and behavior that implementations must enforce in order to support IBC v2 protocol. + +## Packet Structure + +A `Packet` in the interblockchain communication protocol is the primary interface by which applications will send data to counterparty applications on other chains. It is defined as follows: + +```typescript +interface Packet { + sourceClientId: bytes // identifier of the client on the sending chain + destClientId: bytes // identifier of the client on the receiving chain + sequence: uint64 // unique number identifying this packet in the stream of packets from sourceClientId to destClientId + timeoutTimestamp: uint64, // indicates the timeout as a UNIX timestamp in seconds. If the timeout timestamp is reached on destination chain, it is no longer receivable + data: Payload[] // a list of payloads intended for applications on the receiving chain +} +``` + +```typescript +interface Payload { + sourcePort: bytes, // identifier of the sending application on the sending chain + destPort: bytes, // identifier of the receiving application on the receiving chain + version: string, // payload version only interpretable by sending/receiving applications + encoding: string, // payload encoding only interpretable by sending/receiving applications + value: bytes // application-specific data that can be parsed by receiving application given the version and encoding +} +``` + +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. + +Packet Invariants: + +- None of the packet fields are allowed to be empty +- For every payload included, none of the payload fields are allowed to be empty + +## Receipt + +A `Receipt` is a sentinel byte that is stored under the standardized provable ReceiptPath of a given packet by the receiving chain when it successfully receives the packet. This prevents replay attacks and also the possibility of timing out a packet on the sender chain when the packet has already been received. The specific value of the receipt does not matter so long as its not empty. + +## Acknowledgement Structure + +An `Acknowledgement` is the interface that will be used by receiving applications to return application specific information back to the sender. If every application successfully received its payload, then each receiving application will return their custom acknowledgement bytes which will be appended to the acknowledgement array. If **any** application returns an error, then the acknowledgement will have a single element with a sentinel error acknowledgement. + +```typescript +const ErrorAcknowledgement = sha256("UNIVERSAL_ERROR_ACKNOWLEDGEMENT") + +interface Acknowledgement { + appAcknowledgement bytes[] // array of an array of bytes. Each element of the array contains an acknowledgement from a specific application +} +``` + +Acknowledgement Invariants: + +- If the acknowledgement interface includes an error acknowledgement then there must be only a single element in the array with the error acknowledgement +- There CANNOT be multiple app acknowledgements where an element is the error acknowledgement +- If there are multiple app acknowledgements, the length of the app acknowledgements is the same length as the payloads in the associated packet and each acknowledgement is associated with the payload in the same position in the payload array. + +## SendPacket + +SendPacket is called by users to execute an inter-blockchain flow. The user submits a message with a payload(s) for each IBC application they wish to interact with. The SendPacket handler must call the sendPacket logic of each sending application as identified by the sourcePort of the payload. If none of the sending applications error, then the sendPacket handler must construct the packet with the user-provided sourceClient, payloads, and timeout and the destinationClient it retrieves from the counterparty storage given the sourceClient and a generated sequence that is unique for the sourceClientId. It will commit the packet with the ICS24 commitment function under the ICS24 path. The sending chain MAY store the ICS24 path under a custom prefix in the provable store. In this case, the counterparty must have knowledge of the custom prefix as provided by the relayer on setup. The sending chain SHOULD check the provided timestamp against an authenticated time oracle (local BFT time or destination client latest timestamp) and preemptively reject a user-provided packet with a timestamp that has already passed. + +The user may be an off-chain process or an on-chain actor. In either case, the user is not trusted by the IBC protocol. The IBC application is responsible for properly authenticating that the user is allowed to send the requested app data using the IBC application's port as specified in the source port of the payload. The IBC application is also responsible for executing any app-specific logic that must run before the IBC packet can be sent (e.g. escrowing user's tokens before sending a fungible token transfer packet). + +SendPacket Inputs: + +`payloads: Payload[]`: List of payloads that are to be sent from source applications on sending chain to corresponding destination applications on the receiving chain. Implementations MAY choose to only support a single payload per packet. +`sourceClientId: bytes`: Identifier of the receiver chain client that exists on the sending chain. +`timeoutTimestamp: uint64`: The timeout in UNIX seconds after which the packet is no longer receivable on the receiving chain. NOTE: This timestamp is evaluated against the **receiving chain** clock as there may be drift between the sending chain and receiving chain clocks + +SendPacket Preconditions: + +- A valid client exists on the sending chain with the `sourceClientId` +- There exists a mapping on the sending chain from `sourceClientId` to `Counterparty` + +SendPacket Postconditions: + +- The sending application(s) as identified by the source port(s) in the payload(s) have all executed their sendPacket logic successfully +- The following packet gets committed and stored under the packet commitment path as specified by ICS24: + +```typescript +interface Packet { + sourceClientId: sourceClientId, + destClientId: getCounterparty(sourceClientId).ClientId, // destClientId should be filled in with the registered counterparty id for provided sourceClientId + sequence: generateUniqueSequence(sourceClientId), + timeoutTimestamp: timeoutTimestamp + data: payloads +} +``` + +- 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. + +SendPacket Errorconditions: + +- Any of the sending applications returns an error during its sendPacket logic execution +- The sending client is invalid (expired or frozen) + +SendPacket Invariants: + +- The sourceClientId MUST exist on the sending chain +- The destClientId MUST be the registered counterparty of the sourceClientId on the sending chain +- The sending chain MUST NOT have sent a previous packet with the same `sourceClientId` and `sequence` + +## RecvPacket + +RecvPacket is called by relayers once a packet has been committed on the sender chain in order to process the packet on the receiving chain. Since the relayer is not trusted, the relayer must provide a proof that the sender chain had indeed committed the provided packet which will be verified against the `destClient` on the receiving chain. + +If the proof succeeds, and the packet passes replay and timeout checks; then each payload is sent to the receiving application as part of the receiving application callback. + +RecvPacket Inputs: +`packet: Packet`: The packet sent from the sending chain to our chain +`proof: bytes`: An opaque proof that will be sent to the destination client. The destination client is responsible for interpreting the bytes as a proof and verifying the packet commitment key/value provided by the packet handler against the provided proof. +`proofHeight: Number`: This is the height of the counterparty chain from which the proof was generated. A corresponding consensus state for this height must exist on the destination client for the proof to verify correctly. + +RecvPacket Preconditions: + +- A valid client exists on the receiving chain with `destClientId` +- There exists a mapping from `destClientId` to `Counterparty` + +RecvPacket Postconditions: + +- A packet receipt is stored under the specified ICS24 with the `destClientId` and `sequence` +- All receiving application(s) as identified by the destPort(s) in the payload(s) have executed their recvPacket logic. If **any** of the payloads return an error during processing, then all application state changes for all payloads **must** be reverted. If all payloads are processed successfully, then all applications state changes are written. This ensures atomic execution for the payloads batched together in a single packet. +- If any payload returns an error, then the single `SENTINEL ERROR ACKNOWLEDGEMENT` is written using `WriteAcknowledgment`. If all payloads succeed and return an app-specific acknowledgement, then each app acknowledgement is included in the list of `AppAcknowledgement` in the final packet `Acknowledgement` in the **exact** order that their corresponding payloads were included in the packet. + +NOTE: It is possible for applications to process their payload asynchronously to the `RecvPacket` transaction execution. In this case, the IBC core handler **must** await all applications returning their individual application acknowledgements before writing the acknowledgement with app acknowledgements in the order of their corresponding payloads in the original packet **not** the order in which the applications return their asynchronous acknowledgements which may be different orders. IBC allows multiple payloads intended for the same application to be batched in the same packet. Thus, if an implementation wishes to support multiple payloads and asynchronous acknowledgements together, then there must be a way for core IBC to know which payload a particular acknowledgment is being written for. This may be done by providing the index of the payload list during `recvPacket` application callback, so that the application can return the same index when writing the acknowledgment so that it can be placed in the right order. Otherwise, implementations may simply block asynchronous acknowledgment support for multi-payload packets + +RecvPacket Errorconditions: + +- `Counterparty.ClientId` != `packet.sourceClientId` ensures that packet was sent by expected counterparty +- `packet.TimeoutTimestamp` >= `chain.BlockTime()` ensures we cannot receive successfully if packet can be timed out on sending chain +- Packet receipt does not already exist in state for the `destClientId` and `sequence`. This prevents replay attacks +- Membership proof does not successfully verify + +## WriteAcknowledgement + +WriteAcknowledgement Inputs: + +`destClientId: bytes`: Identifier of the sender chain client that exist on the receiving chain +`sequence: uint64`: Unique sequence identifying the packet from sending chain to receiving chain +`ack: Acknowledgement`: Acknowledgement collected by receiving chain from all receiving applications after they have returned their individual acknowledgement. If any individual application errors, the entire acknowledgement MUST have a single element with just the SENTINEL ERROR ACKNOWLEDGEMENT. If all applications successfully received, then every application must have its own acknowledgement set in the `Acknowledgement` in the same order that they existed in the payload of the sending packet. + +WriteAcknowledgement Preconditions: + +- A packet receipt is stored under the specified ICS24 with the `destClientId` and `sequence` +- An acknowledgement for the `destClientId` and `sequence` has not already been written under the ICS24 path + +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. +- 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. + +## AcknowledgePacket + +AcknowledgePacket Inputs: + +`packet: Packet`: The packet that was originally sent by our chain +`acknowledgement: Acknowledgement`: The acknowledgement written by the receiving chain for the packet +`proof: bytes`: An opaque proof that will be sent to the source client. The source client is responsible for interpreting the proof and verifying it against the acknowledgement key/value provided by the packet handler. +`proofHeight: Number`: This is the height of the counterparty chain from which the proof was generated. A corresponding consensus state for this height must exist on the source client for the proof to verify correctly. + +AcknowledgePacket Preconditions: + +- A valid client exists on the sending chain with the `sourceClientId` +- There exists a mapping on the sending chain from `sourceClientId` to `Counterparty` +- A packet commitment has been stored under the ICS24 packet path with `sourceClientId` and `sequence` + +AcknowledgePacket Postconditions: + +- All sending applications execute the ackPacket logic with the payload and the individual acknowledgement for that payload or the universal `ErrorAcknowledgement`. +- Stored commitment for the packet is deleted + +AcknowledgePacket Errorconditions: + +- `packet.destClient` != `counterparty.ClientId`. This should never happen if the second error condition is not true, since we constructed the packet correctly earlier +- The packet provided by the relayer does not commit to the stored commitment we have stored for the `sourceClientId` and `sequence` +- Membership proof of the acknowledgement commitment on the receiving chain as standardized by ICS24 does not verify +- Any of the applications return an error during the `AcknowledgePacket` callback for their payload. Applications should generally not error on AcknowledgePacket. If this occurs, it is most likely a bug so the error should revert the transaction and allow for the bug to be patched before resubmitting the transaction. + +## TimeoutPacket + +TimeoutPacket Inputs: + +`packet: Packet`: The packet that was originally sent by our chain +`proof: bytes`: An opaque non-existence proof that will be sent to the source client. The source client is responsible for interpreting the proof and verifying it against the receipt key provided by the packet handler. +`proofHeight: Number`: This is the height of the counterparty chain from which the proof was generated. A corresponding consensus state for this height must exist on the source client for the proof to verify correctly. + +TimeoutPacket Preconditions: + +- A valid client exists on the sending chain with the `sourceClientId` +- There exists a mapping on the sending chain from `sourceClientId` to `Counterparty` +- A packet commitment has been stored under the ICS24 packet path with `sourceClientId` and `sequence` + +TimeoutPacket Postconditions: + +- All sending applications execute the timeoutPacket logic with the payload. +- Stored commitment for the packet is deleted + +TimeoutPacket Errorconditions: + +- `packet.destClient` != `counterparty.ClientId`. This should never happen if the second error condition is not true, since we constructed the packet correctly earlier +- The packet provided by the relayer does not commit to the stored commitment we have stored for the `sourceClientId` and `sequence` +- Non-Membership proof of the packet receipt on the receiving chain as standardized by ICS24 does not verify +- Any of the applications return an error during the `TimeoutPacket` callback for their payload. Applications should generally not error on TimeoutPacket. If this occurs, it is most likely a bug so the error should revert the transaction and allow for the bug to be patched before resubmitting the transaction. diff --git a/ibc/next/spec/IBC_V2/core/ics-005-port-allocation/README.mdx b/ibc/next/spec/IBC_V2/core/ics-005-port-allocation/README.mdx new file mode 100644 index 00000000..57050290 --- /dev/null +++ b/ibc/next/spec/IBC_V2/core/ics-005-port-allocation/README.mdx @@ -0,0 +1,59 @@ +--- +ics: 5 +title: Port Allocation +stage: draft +category: IBC/TAO +kind: interface +required_by: [4] +version_compatibility: + - ibc-go v10.0.0 +authors: + - name: Aditya Sripal + email: aditya@interchain.io +created: 2024-05-17 +--- + +## Synopsis + +This standard specifies the port allocation system by which modules can bind to uniquely named ports allocated by the IBC handler. +The port identifiers in the packet defines which application to route the packet callback to. The source portID is an identifier of the application sending the packet, thus it will also receive the `AcknowledgePacket` and `TimeoutPacket` callback. The destination portID is the identifier of the application receiving the packet and will receive the `ReceivePacket` callback. + +Modules may register multiple ports on a state machine and send from any of their registered ports to any arbitrary port on a remote state machine. Each port on a state machine must be mapped to a specific IBC module as defined by [ICS-26](../ics-026-application-callbacks/README). Thus the IBC application to portID mapping is one-to-many. + +NOTE: IBC v1 included a channel along with a channel handshake that explicitly associated a unique channel between two portIDs on counterparty chains. Thus, the portIDs on both sides were tightly coupled such that no other application other than the ones bound by the portIDs were allowed to send packets on the dedicated channel. IBC v2 removed the concept of a channel and all packet flow is between chains rather than being isolated module-module communication. Thus, an application on a sending chain is allowed to send a packet to ANY other application on a destination chain by identifying the application with the portIDs in the packet. Thus, it is now the responsibility of applications to restrict which applications are allowed to send packets to them by checking the portID in the callback and rejecting any packet that comes from an unauthorized application. + +### Motivation + +The interblockchain communication protocol is designed to facilitate module-to-module communication, where modules are independent, possibly mutually distrusted, self-contained +elements of code executing on sovereign ledgers. + +## Technical Specification + +### Registering a port + +The IBC handler MUST provide a way for applications to register their callbacks on a portID. + +```typescript +function registerPort(portId: Identifier, cbs: ICS26App) => void +``` + +RegisterPort Preconditions: + +- There is no other application that is registered on the port router for the given `portId`. + +RegisterPort Postconditions: + +- The ICS26 application is registered on the provided `portId`. +- Any incoming packet flow message addressed to the `portId` is routed to the ICS26 application. Any outgoing packet flow message addressed by the `portId` MUST come from the ICS26 application + +### Authenticating and Routing Packet Flow Messages + +Once an application is registered with a port, it is the port router's responsibility to properly route packet flow messages to the appropriate application identified by the portId in the payload. Similarly when the application sends packet flow messages to the port router, the router MUST ensure that the application is authenticated to send the packet flow message by checking if the payload portIDs are registered to the application. + +For packet flow messages on the packet sending chain (e.g. `SendPacket`, `AcknowledgePacket`, `TimeoutPacket`); the port router MUST do this authentication and routing using the packet payload's `sourcePortId`. + +For packet flow messages on the packet receiving chain (e.g. `RecvPacket` and optionally the asynchronous `WriteAcknowledgement`); the port router MUST do this authentication and routing using the packet payload's `destPortId`. + +[ICS-4](../ics-004-packet-semantics/PACKET_HANDLER) defines the packet flow messages and the expected behavior of their respected handlers. When the packet flow message arrives from the core ICS-4 handler to the application (e.g. `RecvPacket`, `AcknowledgePacket`, `TimeoutPacket`); then the portRouter acts as a router routing the message from the core handler to the ICS26 application. When the packet flow message arrives from the application to the core ICS-4 handler (e.g. `SendPacket`, or the optional `WriteAcknowledgement`); then the portRouter acts as an authenticator by checking that the calling application is registered as the owner of port they wish to send the message on before sending the message to the ICS-4 handler. + +NOTE: It is possible for implementations to change the order of execution flow so long as they still respect all the expected semantics and behavior defined in ICS-4. In this case, the port router's role as router or authenticator will change accordingly. diff --git a/ibc/next/spec/IBC_V2/core/ics-024-host-requirements/README.mdx b/ibc/next/spec/IBC_V2/core/ics-024-host-requirements/README.mdx new file mode 100644 index 00000000..4d9ba4d5 --- /dev/null +++ b/ibc/next/spec/IBC_V2/core/ics-024-host-requirements/README.mdx @@ -0,0 +1,148 @@ +--- +ics: 24 +title: Host State Machine Requirements +stage: draft +category: IBC/TAO +kind: interface +required_by: [4] +version_compatibility: + - ibc-go v10.0.0 +authors: + - name: Aditya Sripal + email: aditya@interchain.io +created: 2024-08-21 +modified: 2024-08-21 +--- + + +## Synopsis + +This specification defines the minimal set of properties which must be fulfilled by a state machine hosting an implementation of the interblockchain communication protocol. IBC relies on a key-value provable store for cross-chain communication. In version 2 of the specification, the expected key-value storage will only be for the keys that are relevant for packet processing. + +### Motivation + +IBC is designed to be a common standard which will be hosted by a variety of blockchains & state machines and must clearly define the requirements of the host. + +### Definitions + +### Desired Properties + +IBC should require as simple an interface from the underlying state machine as possible to maximise the ease of correct implementation. + +## Technical Specification + +### Module system + +The host state machine must support a module system, whereby self-contained, potentially mutually distrusted packages of code can safely execute on the same ledger, control how and when they allow other modules to communicate with them, and be identified and manipulated by a "master module" or execution environment. + +The IBC core handlers as defined in ICS-4 must have + +### Paths, identifiers, separators + +An `Identifier` is a bytestring used as a key for an object stored in state, such as a packet commitment, acknowledgement, or receipt. + +Identifiers MUST be non-empty (of positive integer length). + +Identifiers MUST consist of characters in one of the following categories only: + +- Alphanumeric +- `.`, `_`, `+`, `-`, `#` +- `[`, `]`, `<`, `>` + +A `Path` is a bytestring used as the key for an object stored in state. Paths MUST contain only identifiers, constant bytestrings, and the separator `"/"`. + +Identifiers are not intended to be valuable resources — to prevent name squatting, minimum length requirements or pseudorandom generation MAY be implemented, but particular restrictions are not imposed by this specification. + +The separator `"/"` is used to separate and concatenate two identifiers or an identifier and a constant bytestring. Identifiers MUST NOT contain the `"/"` character, which prevents ambiguity. + +By default, identifiers have the following minimum and maximum lengths in characters: + +| Port identifier | Client identifier | +| --------------- | ----------------- | +| 2 - 128 | 2 - 64 | + +### Key/value Store + +The host state machine MUST provide a key/value store interface +with three functions that behave in the standard way: + +```typescript +type get = (path: Path) => Value | void +``` + +```typescript +type set = (path: Path, value: Value) => void +``` + +```typescript +type queryProof = (path: Path) => (CommitmentProof, Value) +``` + +`queryProof` will return a `Membership` proof if there exists a value for that path in the key/value store and a `NonMembership` proof if there is no value stored for the path. + +The host state machine SHOULD provide an interface for deleting +a Path from the key/value store as well though it is not required: + +```typescript +type delete = (path: Path) => void +``` + +`Path` is as defined above. `Value` is an arbitrary bytestring encoding of a particular data structure. The specific Path and Values required to be written to the provable store are defined in [ICS-4](../ics-004-packet-semantics/PACKET). + +These functions MUST be permissioned to the IBC packet handler module (the implementation of which is described in [ICS-4](../ics-004-packet-semantics/PACKET_HANDLER)) only, so only the IBC handler module can `set` or `delete` the paths that can be read by `get`. + +In most cases, this will be implemented as a sub-store (prefixed key-space) of a larger key/value store used by the entire state machine. This is why ICS-2 defines a `counterpartyCommitmentPrefix` that is associated with the client. The IBC handler will prefix the `counterpartyCommitmentPrefix` to the ICS-4 standardized path before proof verification against a `ConsensusState` in the client. + +### Provable Path-space + +IBC/TAO implementations MUST implement the following paths for the `provableStore` in the exact format specified. This is because counterparty IBC/TAO implementations will construct the paths according to this specification and send it to the light client to verify the IBC specified value stored under the IBC specified path. + +Future paths may be used in future versions of the protocol, so the entire key-space in the provable store MUST be reserved for the IBC handler. + +| Value | Path format | +| -------------------------- | -------------------------------------------- | +| Packet Commitment | {sourceClientId}0x1{bigEndianUint64Sequence} | +| 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). + +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. + +The provable store MUST be capable of providing `MembershipProof` for a key/value pair that exists in the store. It MUST also be capable of providing a `NonMembership` proof for a key that does not exist in the store. + +In the case, the state machine does not support `NonMembership` proofs; a client may get around this restriction by associating a `SENTINEL_ABSENCE_VALUE` with meaning the key does not exist and treating a `MembershipProof` with a `SENTINEL_ABSENCE_VALUE` as a `NonMembershipProof`. In this case, the state machine is responsible for ensuring that there is a way to write a `SENTINEL_ABSENCE_VALUE` to the keys that IBC needs to prove nonmembership for and it MUST ensure that an actor cannot set the `SENTINEL_ABSENCE_VALUE` directly for a key accidentally. These requirements and how to implement them are outside the scope of this specification and remain the responsibility of the bespoke IBC implementation. + +### Finality + +The state machine MUST make updates sequentially so that all state updates happen in order and can be associated with a unique `Height` in that order. Each state update at a height `h` MUST be eventually **finalized** at a finite timestamp `t` such that the order of state updates from the initial state up to `h` will never change after time `t`. + +IBC handlers will only accept packet-flow messages from state updates which are already deemed to be finalized. In cases where the finality property is probabilistically guaranteed, this probabilitic guarantee must be handled within the ICS-2 client in order to provide a final view of the remote state machine for the ICS-4 packet handler. + +### Time + +As the state updates are applied to the state machine over time, the state update algorithm MUST itself have secure access to the current timestamp at which the state update is being applied. This is needed for IBC handlers to process timeouts correctly. + +If the state machine update mechanism does not itself provide a timestamp to the state machine handler, then there must be a time oracle updates as part of the state machine update itself. In this case, the security model of IBC will also include the security model of the time oracle. + +This timestamp for a state update MUST be monotonically increasing and it MUST be the greater than or equal to the timestamp that the counterparty client will return for the `ConsensusState` associated with that state update. + +## Backwards Compatibility + +Not applicable. + +## Forwards Compatibility + +Key/value store functionality and consensus state type are unlikely to change during operation of a single host state machine. + +`submitDatagram` can change over time as relayers should be able to update their processes. + +## Example Implementations + +## History + +Aug 21, 2024 - [Initial draft](https://github.com/cosmos/ibc/pull/1144) + +## Copyright + +All content herein is licensed under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0). diff --git a/ibc/next/spec/IBC_V2/core/ics-026-application-callbacks/README.mdx b/ibc/next/spec/IBC_V2/core/ics-026-application-callbacks/README.mdx new file mode 100644 index 00000000..adb92786 --- /dev/null +++ b/ibc/next/spec/IBC_V2/core/ics-026-application-callbacks/README.mdx @@ -0,0 +1,184 @@ +--- +ics: 26 +title: IBC Application Callbacks +stage: draft +category: IBC/TAO +kind: instantiation +version_compatibility: + - ibc-go v10.0.0 +authors: + - name: Aditya Sripal + email: aditya@interchain.io +created: 2025-03-19 +--- + + +## Synopsis + +IBC enables module to module communication across remote state machines by providing a secure packet flow authenticated by the ICS-4 packet handler. The IBC core protocol is responsible for TAO (transport, authentication, ordering) of packets between two chains. These packets contain payload(s) that carry the application-specific information that is being communicated between two ICS26 applications. The data in the payload is itself opaque to the IBC core protocol, IBC core only verifies that it was correctly sent by the sender and then provides that data to the receiver for application-specific interpretation and processing. + +This specification standardizes the interface between ICS-4 (core IBC/TAO) and an IBC application (i.e. ICS26 app) for all the packet flow messages. + +The default IBC handler uses a receiver call pattern, where modules must individually call the IBC handler in order to send packets. In turn, the IBC handler verifies incoming packet flow messages like `ReceivePacket`, `AcknowledgePacket` and `TimeoutPacket` and calls into the appropriate ICS26 application as described in [ICS5 Port Allocation](../ics-005-port-allocation/README). + +## Technical Specification + +### Payload Structure + +The payload structure is reproduced from [ICS-4](../ics-004-packet-semantics/PACKET) since all of the following application functions are operating on the payloads that are being sent in the packets. + +```typescript +interface Payload { + sourcePort: bytes, // identifier of the sending application on the sending chain + destPort: bytes, // identifier of the receiving application on the receiving chain + version: string, // payload version only interpretable by sending/receiving applications + encoding: string, // payload encoding only interpretable by sending/receiving applications + value: bytes // application-specific data that can be parsed by receiving application given the version and encoding +} +``` + +### Core Handler Interface Exposed to ICS26 Applications + +The IBC core handler MUST expose the following function signature to the ICS26 applications registered on the port router, so that the application can send packets. + +#### SendPacket + +SendPacket Inputs: + +`payloads: Payload`: This is the payload that the application wishes to send to an application on the receiver chain. +`sourceClientId: bytes`: Identifier of the receiver chain client that exists on the sending chain. +`timeoutTimestamp: uint64`: The timeout in UNIX seconds after which the packet is no longer receivable on the receiving chain. NOTE: This timestamp is evaluated against the **receiving chain** clock as there may be drift between the sending chain and receiving chain clocks + +SendPacket Preconditions: + +- The application is registered on the port router with `payload.SourcePortId` +- The application MUST have successfully conducted any application specific logic necessary for sending the given payload. +- The sending client exists for `sourceClientId` + +SendPacket Postconditions: + +- The following packet gets committed and stored under the packet commitment path as specified by ICS24: + +```typescript +interface Packet { + sourceClientId: sourceClientId, + destClientId: getCounterparty(sourceClientId).ClientId, // destClientId should be filled in with the registered counterparty id for provided sourceClientId + sequence: generateUniqueSequence(sourceClientId), + timeoutTimestamp: msg.timeoutTimestamp + data: msg.Payloads +} +``` + +- The sequence is returned to the ICS26 application + +SendPacket ErrorConditions: + +- The sending client is invalid (expired or frozen) +- The provided `timeoutTimstamp` has already elapsed +- The sending application is not allowed to send the provided payload to the requested receiving application as identified by `payload.DestPort` + +NOTE: IBC v2 allows multiple payloads coming from multiple applications to be sent in the same packet. If an implementation chooses to support this feature, they may either provide an entrypoint in the core handler to send multiple packets, which must then call each individual application `OnSendPacket` callback to validate their individual payload and do application-specific sending logic; or they may queue the payloads coming from each application until the packet is ready to be committed. + +#### 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. + +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. + +WriteAcknowledgement Inputs: + +`destClientId: bytes`: Identifier of the sender chain client that exist on the receiving chain (i.e. executing chain) +`sequence: uint64`: Unique sequence identifying the packet from sending chain to receiving chain +`ack: bytes`: Acknowledgement from the receiving application for the payload it was sent by the application. If the receive was unsuccessful, the `ack` must be the `SENTINEL_ERROR_ACKNOWLEDGEMENT`, otherwise it may be some application-specific data. + +WriteAcknowledgement Preconditions: + +- A packet receipt is stored under the specified ICS24 with the `destClientId` and `sequence` +- An acknowledgement for the `destClientId` and `sequence` has not already been written under the ICS24 path + +WriteAcknowledgement Postconditions: + +- The acknowledgement is committed and written to the acknowledgement path as specified in ICS24 +- 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. + +### ICS26 Interface Exposed to Core Handler + +Modules must expose the following function signatures to the routing module, which are called upon the receipt of various datagrams: + +#### OnRecvPacket + +OnRecvPacket Inputs: + +`sourceClientId: bytes`: This is the identifier of the client on the sending chain. NOTE: This is an identifier on the counterparty chain provided as information for the application, but it should not be treated as a unique identifier on the receiving chain. +`destClientId: bytes`: This is the identifier of the receiving chain (i.e. executing chain) +`sequence: uint64`: This is the unique sequence for the packet in the stream of packets from sending chain to destination chain. The tuple `(destClientId, sequence)` uniquely identifies the packet on this chain. +`payload: Payload`. This is the payload that an application registered by `payload.SourcePort` on the sending chain sends to the executing application + +OnRecvPacket Preconditions: + +- The application is registered on the port router with `payload.DestPort` +- The destination client exists for `destClientId` +- All IBC/TAO verification checks have already been authenticated by IBC core handler. Thus, when the application receives a packet; it can be guaranteed of its authenticity and need only perform the relevant application logic for the given payload. + +OnRecvPacket Postconditions: + +- The application has executed all app-specific logic for the given payload and made the appropriate state changes +- The application returns an app acknowledgment `ack: bytes` to the core IBC handler to be written as an acknowledgement of the payload in this packet. + +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`. + +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. + +#### OnAcknowledgePacket + +OnAcknowledgePacket Inputs: + +`sourceClientId: bytes`: This is the identifier of the client on the sending chain (i.e. executing chain). +`destClientId: bytes`: This is the identifier of the receiving chain. NOTE: This is an identifier on the counterparty chain provided as information for the application, but it should not be treated as a unique identifier on the receiving chain. +`sequence: uint64`: This is the unique sequence for the packet in the stream of packets from sending chain to destination chain. The tuple `(sourceClientId, sequence)` uniquely identifies the packet on this chain. +`acknowledgement: bytes`: This is the acknowledgement that the receiving application sent for the payload that we previously sent. It may be a successful acknowledgement with app-specific information or it may be the `SENTINEL_ERROR_ACKNOWLEDGEMENT` in which case we should handle any app-specific logic needed for a packet that failed to be sent. +`payload: Payload`: This is the original payload that we previously sent + +OnAcknowledgementPreconditions: + +- This application had previously sent the provided payload in a packet with the provided `sourceClientId` and `sequence`. +- All IBC/TAO verification checks have already been authenticated by IBC core handler. Thus, when the application receives an acknowledgement; it can be guaranteed of its authenticity and need only perform the relevant application logic for the given acknowledgement and payload. + +OnAcknowledgement Postconditions: + +- The application has executed all app-specific logic for the given payload and acknowledgment and made the appropriate state changes +- If the acknowledgement was the `SENTINEL_ERROR_ACKNOWLEDGEMENT`, this will usually involve reverting whatever application state changes were made during `SendPacket` (e.g. unescrowing tokens for transfer) + +OnAcknowledgement Errorconditions: + +- Application specific errors may occur while processing the acknowledgement. The packet lifecycle is already complete. Implementations MAY choose to allow retries or not. + +#### OnTimeoutPacket + +OnTimeoutPacket Inputs: + +`sourceClientId: bytes`: This is the identifier of the client on the sending chain (i.e. executing chain). +`destClientId: bytes`: This is the identifier of the receiving chain. NOTE: This is an identifier on the counterparty chain provided as information for the application, but it should not be treated as a unique identifier on the receiving chain. +`sequence: uint64`: This is the unique sequence for the packet in the stream of packets from sending chain to destination chain. The tuple `(sourceClientId, sequence)` uniquely identifies the packet on this chain. +`payload: Payload`: This is the original payload that we previously sent + +OnTimeoutPacket Preconditions: + +- This application had previously sent the provided payload in a packet with the provided `sourceClientId` and `sequence`. +- All IBC/TAO verification checks have already been authenticated by IBC core handler. Thus, when the application receives an timeout; it can be guaranteed of its authenticity and need only perform the relevant application timeout logic for the given payload. + +OnTimeoutPacket Postconditions: + +- The application has executed all app-specific logic for the given payload and made the appropriate state changes. This will usually involve reverting whatever application state changes were made during `SendPacket` (e.g. unescrowing tokens for transfer) + +OnTimeoutPacket Errorconditions: + +- Application specific errors may occur while processing the timeout. The packet lifecycle is already complete. Implementations MAY choose to allow retries or not. diff --git a/ibc/next/spec/app/ics-020-fungible-token-transfer/README.mdx b/ibc/next/spec/app/ics-020-fungible-token-transfer/README.mdx new file mode 100644 index 00000000..577c5392 --- /dev/null +++ b/ibc/next/spec/app/ics-020-fungible-token-transfer/README.mdx @@ -0,0 +1,452 @@ +--- +ics: 20 +title: Fungible Token Transfer +version: 1 +stage: draft +category: IBC/APP +requires: [25, 26] +kind: instantiation +version_compatibility: + - ibc-go v10.0.0 + - ibc-rs v0.53.0 +author: + name: Christopher Goes + email: cwgoes@interchain.berlin +created: 2019-07-15 +modified: 2020-02-24 +--- + + +## Synopsis + +This standard document specifies packet data structure, state machine handling logic, and encoding details for the transfer of fungible tokens over an IBC channel between two modules on separate chains. The state machine logic presented allows for safe multi-chain denomination handling with permissionless channel opening. This logic constitutes a "fungible token transfer bridge module", interfacing between the IBC routing module and an existing asset tracking module on the host state machine. + +### Motivation + +Users of a set of chains connected over the IBC protocol might wish to utilise an asset issued on one chain on another chain, perhaps to make use of additional features such as exchange or privacy protection, while retaining fungibility with the original asset on the issuing chain. This application-layer standard describes a protocol for transferring fungible tokens between chains connected with IBC which preserves asset fungibility, preserves asset ownership, limits the impact of Byzantine faults, and requires no additional permissioning. + +### Definitions + +The IBC handler interface & IBC routing module interface are as defined in [ICS 25](../../core/ics-025-handler-interface) and [ICS 26](../../core/ics-026-routing-module), respectively. + +### Desired Properties + +- Preservation of fungibility (two-way peg). +- Preservation of total supply (constant or inflationary on a single source chain & module). +- Permissionless token transfers, no need to whitelist connections, modules, or denominations. +- Symmetric (all chains implement the same logic, no in-protocol differentiation of hubs & zones). +- Fault containment: prevents Byzantine-inflation of tokens originating on chain `A`, as a result of chain `B`'s Byzantine behaviour (though any users who sent tokens to chain `B` may be at risk). + +## Technical Specification + +### Data Structures + +Only one packet data type is required: `FungibleTokenPacketData`, which specifies the denomination, amount, sending account, and receiving account. + +```typescript +interface FungibleTokenPacketData { + denom: string + amount: uint256 + sender: string + receiver: string + memo: string +} +``` + +As tokens are sent across chains using the ICS 20 protocol, they begin to accrue a record of channels for which they have been transferred across. This information is encoded into the `denom` field. + +The ICS 20 token denominations are represented by the form `{ics20Port}/{ics20Channel}/{denom}`, where `ics20Port` and `ics20Channel` are an ICS 20 port and channel on the current chain for which the funds exist. The prefixed port and channel pair indicate which channel the funds were previously sent through. Implementations are responsible for correctly parsing the IBC trace information from the base denomination. The way the reference ICS 20 implementation in ibc-go handles this is by taking advantage of the fact that it automatically generates channel identifiers with the format `channel-{n}`, where `n` is a integer greater or equal than 0. It can then correctly parse out the IBC trace information from the base denom which may have slashes, but will not have a substring of the form `{transfer-port-name}/channel-{n}`. If this assumption is broken, the trace information will be parsed incorrectly (i.e. part of the base denom will be misinterpreted as trace information). Thus chains must make sure that base denominations do not have the ability to create arbitrary prefixes that can mock the ICS 20 logic. + +A sending chain may be acting as a source or sink zone. When a chain is sending tokens across a port and channel which are not equal to the last prefixed port and channel pair, it is acting as a source zone. When tokens are sent from a source zone, the destination port and channel will be prefixed onto the denomination (once the tokens are received) adding another hop to a tokens record. When a chain is sending tokens across a port and channel which are equal to the last prefixed port and channel pair, it is acting as a sink zone. When tokens are sent from a sink zone, the last prefixed port and channel pair on the denomination is removed (once the tokens are received), undoing the last hop in the tokens record. A more complete explanation is present in the [ibc-go implementation](https://github.com/cosmos/ibc-go/blob/457095517b7832c42ecf13571fee1e550fec02d0/modules/apps/transfer/keeper/relay.go#L18-L49) and the [ADR 001](https://github.com/cosmos/ibc-go/blob/main/docs/architecture/adr-001-coin-source-tracing.md). + +The following sequence diagram exemplifies the multi-chain token transfer dynamics. This process encapsulates the steps involved in transferring tokens in a cycle that begins and ends on the same chain, traversing through Chain A, Chain B, and Chain C. The order of operations is outlined as `A -> B -> C -> A -> C -> B -> A`. + +```mermaid +sequenceDiagram + Note over chain A,chain B: A is source zone: A -> B + chain A->>chain A: Lock (escrow) tokens ("denom") + chain A->>chain B: Send transfer packet with tokens ("denom") + chain B->>chain B: Mint vouchers ("transfer/ChannelToA/denom") + Note over chain B,chain C: B is source zone: B -> C + chain B->>chain B: Lock (escrow) vouchers ("transfer/ChannelToA/denom") + chain B->>chain C: Send transfer packet with vouchers ("transfer/ChannelToA/denom") + chain C->>chain C: Mint vouchers ("transfer/ChannelToB/transfer/ChannelToA/denom") + 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") + 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") + chain C->>chain C: Unlock (unescrow) vouchers ("transfer/ChannelToB/transfer/ChannelToA/denom") + Note over chain B,chain C: C is sink zone: C -> B + chain C->>chain C: Burn vouchers ("transfer/ChannelToB/transfer/ChannelToA/denom") + chain C->>chain B: Send transfer packet with vouchers ("transfer/ChannelToB/transfer/ChannelToA/denom") + chain B->>chain B: Unlock (unescrow) vouchers ("transfer/ChannelToA/denom") + Note over chain B,chain A: B is sink zone: B -> A + chain B->>chain B: Burn vouchers ("transfer/ChannelToB/transfer/ChannelToA/denom") + chain B->>chain A: Send transfer packet with vouchers ("transfer/ChannelToB/transfer/ChannelToA/denom") + chain A->>chain A: Unlock (unescrow) vouchers ("transfer/ChannelToA/denom") +``` + +The acknowledgement data type describes whether the transfer succeeded or failed, and the reason for failure (if any). + +```typescript +type FungibleTokenPacketAcknowledgement = FungibleTokenPacketSuccess | FungibleTokenPacketError; + +interface FungibleTokenPacketSuccess { + // This is binary 0x01 base64 encoded + result: "AQ==" +} + +interface FungibleTokenPacketError { + error: string +} +``` + +Note that both the `FungibleTokenPacketData` as well as `FungibleTokenPacketAcknowledgement` must be JSON-encoded (not Protobuf encoded) when they serialized into packet data. Also note that `uint256` is string encoded when converted to JSON, but must be a valid decimal number of the form `[0-9]+`. + +The fungible token transfer bridge module tracks escrow addresses associated with particular channels in state. Fields of the `ModuleState` are assumed to be in scope. + +```typescript +interface ModuleState { + channelEscrowAddresses: Map +} +``` + +### Sub-protocols + +The sub-protocols described herein should be implemented in a "fungible token transfer bridge" module with access to a bank module and to the IBC routing module. + +#### Port & channel setup + +The `setup` function must be called exactly once when the module is created (perhaps when the blockchain itself is initialised) to bind to the appropriate port and create an escrow address (owned by the module). + +```typescript +function setup() { + capability = routingModule.bindPort("transfer", ModuleCallbacks{ + onChanOpenInit, + onChanOpenTry, + onChanOpenAck, + onChanOpenConfirm, + onChanCloseInit, + onChanCloseConfirm, + onRecvPacket, + onTimeoutPacket, + onAcknowledgePacket, + onTimeoutPacketClose + }) + claimCapability("port", capability) +} +``` + +Once the `setup` function has been called, channels can be created through the IBC routing module between instances of the fungible token transfer module on separate chains. + +An administrator (with the permissions to create connections & channels on the host state machine) is responsible for setting up connections to other state machines & creating channels +to other instances of this module (or another module supporting this interface) on other chains. This specification defines packet handling semantics only, and defines them in such a fashion +that the module itself doesn't need to worry about what connections or channels might or might not exist at any point in time. + +#### Routing module callbacks + +##### Channel lifecycle management + +Both machines `A` and `B` accept new channels from any module on another machine, if and only if: + +- The channel being created is unordered. +- The version string is `ics20-1`. + +```typescript +function onChanOpenInit( + order: ChannelOrder, + connectionHops: [Identifier], + portIdentifier: Identifier, + channelIdentifier: Identifier, + counterpartyPortIdentifier: Identifier, + counterpartyChannelIdentifier: Identifier, + version: string) => (version: string, err: Error) { + // only unordered channels allowed + abortTransactionUnless(order === UNORDERED) + // assert that version is "ics20-1" or empty + // if empty, we return the default transfer version to core IBC + // as the version for this channel + abortTransactionUnless(version === "ics20-1" || version === "") + // allocate an escrow address + channelEscrowAddresses[channelIdentifier] = newAddress(portIdentifier, channelIdentifier) + return "ics20-1", nil +} +``` + +```typescript +function onChanOpenTry( + order: ChannelOrder, + connectionHops: [Identifier], + portIdentifier: Identifier, + channelIdentifier: Identifier, + counterpartyPortIdentifier: Identifier, + counterpartyChannelIdentifier: Identifier, + counterpartyVersion: string) => (version: string, err: Error) { + // only unordered channels allowed + abortTransactionUnless(order === UNORDERED) + // assert that version is "ics20-1" + abortTransactionUnless(counterpartyVersion === "ics20-1") + // allocate an escrow address + channelEscrowAddresses[channelIdentifier] = newAddress(portIdentifier, channelIdentifier) + // return version that this chain will use given the + // counterparty version + return "ics20-1", nil +} +``` + +```typescript +function onChanOpenAck( + portIdentifier: Identifier, + channelIdentifier: Identifier, + counterpartyChannelIdentifier: Identifier, + counterpartyVersion: string) { + // port has already been validated + // assert that counterparty selected version is "ics20-1" + abortTransactionUnless(counterpartyVersion === "ics20-1") +} +``` + +```typescript +function onChanOpenConfirm( + portIdentifier: Identifier, + channelIdentifier: Identifier) { + // accept channel confirmations, port has already been validated, version has already been validated +} +``` + +```typescript +function onChanCloseInit( + portIdentifier: Identifier, + channelIdentifier: Identifier) { + // always abort transaction + abortTransactionUnless(FALSE) +} +``` + +```typescript +function onChanCloseConfirm( + portIdentifier: Identifier, + channelIdentifier: Identifier) { + // no action necessary +} +``` + +##### Packet relay + +In plain English, between chains `A` and `B`: + +- When acting as the source zone, the bridge module escrows an existing local asset denomination on the sending chain and mints vouchers on the receiving chain. +- When acting as the sink zone, the bridge module burns local vouchers on the sending chains and unescrows the local asset denomination on the receiving chain. +- When a packet times-out, local assets are unescrowed back to the sender or vouchers minted back to the sender appropriately. +- Acknowledgement data is used to handle failures, such as invalid denominations or invalid destination accounts. Returning + an acknowledgement of failure is preferable to aborting the transaction since it more easily enables the sending chain + to take appropriate action based on the nature of the failure. + +`sendFungibleTokens` must be called by a transaction handler in the module which performs appropriate signature checks, specific to the account owner on the host state machine. + +```typescript +function sendFungibleTokens( + denomination: string, + amount: uint256, + sender: string, + receiver: string, + sourcePort: string, + sourceChannel: string, + timeoutHeight: Height, + timeoutTimestamp: uint64, // in unix nanoseconds +): uint64 { + prefix = "{sourcePort}/{sourceChannel}/" + // we are the source if the denomination is not prefixed + source = denomination.slice(0, len(prefix)) !== prefix + if source { + // determine escrow account + escrowAccount = channelEscrowAddresses[sourceChannel] + // escrow source tokens (assumed to fail if balance insufficient) + bank.TransferCoins(sender, escrowAccount, denomination, amount) + } else { + // receiver is source chain, burn vouchers + bank.BurnCoins(sender, denomination, amount) + } + + // create FungibleTokenPacket data + data = FungibleTokenPacketData{denomination, amount, sender, receiver} + + // send packet using the interface defined in ICS4 + sequence = handler.sendPacket( + getCapability("port"), + sourcePort, + sourceChannel, + timeoutHeight, + timeoutTimestamp, + json.marshal(data) // json-marshalled bytes of packet data + ) + + return sequence +} +``` + +`onRecvPacket` is called by the routing module when a packet addressed to this module has been received. + +```typescript +function onRecvPacket(packet: Packet) { + FungibleTokenPacketData data = packet.data + assert(data.denom !== "") + assert(data.amount > 0) + assert(data.sender !== "") + assert(data.receiver !== "") + + // construct default acknowledgement of success + FungibleTokenPacketAcknowledgement ack = FungibleTokenPacketAcknowledgement{true, null} + prefix = "{packet.sourcePort}/{packet.sourceChannel}/" + // we are the source if the packets were prefixed by the sending chain + source = data.denom.slice(0, len(prefix)) === prefix + if source { + // receiver is source chain: unescrow tokens + // determine escrow account + escrowAccount = channelEscrowAddresses[packet.destChannel] + // unescrow tokens to receiver (assumed to fail if balance insufficient) + err = bank.TransferCoins(escrowAccount, data.receiver, data.denom.slice(len(prefix)), data.amount) + if (err !== nil) + ack = FungibleTokenPacketAcknowledgement{false, "transfer coins failed"} + } else { + prefix = "{packet.destPort}/{packet.destChannel}/" + prefixedDenomination = prefix + data.denom + // sender was source, mint vouchers to receiver (assumed to fail if balance insufficient) + err = bank.MintCoins(data.receiver, prefixedDenomination, data.amount) + if (err !== nil) + ack = FungibleTokenPacketAcknowledgement{false, "mint coins failed"} + } + return ack +} +``` + +`onAcknowledgePacket` is called by the routing module when a packet sent by this module has been acknowledged. + +```typescript +function onAcknowledgePacket( + packet: Packet, + acknowledgement: bytes) { + // if the transfer failed, refund the tokens + if (!acknowledgement.success) + refundTokens(packet) +} +``` + +`onTimeoutPacket` is called by the routing module when a packet sent by this module has timed-out (such that it will not be received on the destination chain). + +```typescript +function onTimeoutPacket(packet: Packet) { + // the packet timed-out, so refund the tokens + refundTokens(packet) +} +``` + +`refundTokens` is called by both `onAcknowledgePacket`, on failure, and `onTimeoutPacket`, to refund escrowed tokens to the original sender. + +```typescript +function refundTokens(packet: Packet) { + FungibleTokenPacketData data = packet.data + prefix = "{packet.sourcePort}/{packet.sourceChannel}/" + // we are the source if the denomination is not prefixed + source = data.denom.slice(0, len(prefix)) !== prefix + if source { + // sender was source chain, unescrow tokens back to sender + escrowAccount = channelEscrowAddresses[packet.srcChannel] + bank.TransferCoins(escrowAccount, data.sender, data.denom, data.amount) + } else { + // receiver was source chain, mint vouchers back to sender + bank.MintCoins(data.sender, data.denom, data.amount) + } +} +``` + +```typescript +function onTimeoutPacketClose(packet: Packet) { + // can't happen, only unordered channels allowed +} +``` + +#### Using the Memo Field + +Note: Since earlier versions of this specification did not include a `memo` field, implementations must ensure that the new packet data is still compatible with chains that expect the old packet data. A legacy implementation MUST be able to unmarshal a new packet data with an empty string memo into the legacy `FungibleTokenPacketData` struct. Similarly, an implementation supporting `memo` must be able to unmarshal a legacy packet data into the current struct with the `memo` field set to the empty string. + +The `memo` field is not used within transfer, however it may be used either for external off-chain users (i.e. exchanges) or for middleware wrapping transfer that can parse and execute custom logic on the basis of the passed in memo. If the memo is intended to be parsed and interpreted by higher-level middleware, then these middleware are advised to namespace their additions to the memo string so that they do not overwrite each other. Chains should ensure that there is some length limit on the entire packet data to ensure that the packet does not become a DOS vector. However, these do not need to be protocol-defined limits. If the receiver cannot accept a packet because of length limitations, this will lead to a timeout on the sender side. + +Memos that are intended to be read by higher level middleware for custom execution must be structured so that different middleware can read relevant data in the memo intended for them without interfering with data intended for other middlewares. + +Thus, for any memo that is meant to be interpreted by the state machine; it is recommended that the memo is a JSON object with each middleware reserving a key that it can read into and retrieve relevant data. This way the memo can be constructed to pass in information such that multiple middleware can read the memo without interference from each other. + +Example: + +```json +{ + "wasm": { + "address": "contractAddress", + "arguments": "marshalledArguments", + }, + "callback": "contractAddress", + "router": "routerArgs", +} +``` + +Here, the "wasm", "callback", and "router" fields are all intended for separate middlewares that will exclusively read those fields respectively in order to execute their logic. This allows multiple modules to read from the memo. Middleware should take care to reserve a unique key so that they do not accidentally read data intended for a different module. This issue can be avoided by some off-chain registry of keys already in-use in the JSON object. + +#### Reasoning + +##### Correctness + +This implementation preserves both fungibility & supply. + +Fungibility: If tokens have been sent to the counterparty chain, they can be redeemed back in the same denomination & amount on the source chain. + +Supply: Redefine supply as unlocked tokens. All send-recv pairs sum to net zero. Source chain can change supply. + +##### Multi-chain notes + +This specification does not directly handle the "diamond problem", where a user sends a token originating on chain A to chain B, then to chain D, and wants to return it through D -> C -> A — since the supply is tracked as owned by chain B (and the denomination will be "{portOnD}/{channelOnD}/{portOnB}/{channelOnB}/denom"), chain C cannot serve as the intermediary. It is not yet clear whether that case should be dealt with in-protocol or not — it may be fine to just require the original path of redemption (and if there is frequent liquidity and some surplus on both paths the diamond path will work most of the time). Complexities arising from long redemption paths may lead to the emergence of central chains in the network topology. + +In order to track all of the denominations moving around the network of chains in various paths, it may be helpful for a particular chain to implement a registry which will track the "global" source chain for each denomination. End-user service providers (such as wallet authors) may want to integrate such a registry or keep their own mapping of canonical source chains and human-readable names in order to improve UX. + +#### Optional addenda + +- Each chain, locally, could elect to keep a lookup table to use short, user-friendly local denominations in state which are translated to and from the longer denominations when sending and receiving packets. +- Additional restrictions may be imposed on which other machines may be connected to & which channels may be established. + +## Backwards Compatibility + +Not applicable. + +## Forwards Compatibility + +This initial standard uses version "ics20-1" in the channel handshake. + +A future version of this standard could use a different version in the channel handshake, +and safely alter the packet data format & packet handler semantics. + +## Example Implementations + +- Implementation of ICS 20 in Go can be found in [ibc-go repository](https://github.com/cosmos/ibc-go). +- Implementation of ICS 20 in Rust can be found in [ibc-rs repository](https://github.com/cosmos/ibc-rs). + +## History + +Jul 15, 2019 - Draft written + +Jul 29, 2019 - Major revisions; cleanup + +Aug 25, 2019 - Major revisions, more cleanup + +Feb 3, 2020 - Revisions to handle acknowledgements of success & failure + +Feb 24, 2020 - Revisions to infer source field, inclusion of version string + +July 27, 2020 - Re-addition of source field + +Nov 11, 2022 - Addition of a memo field + +## Copyright + +All content herein is licensed under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0). diff --git a/ibc/next/spec/app/ics-020-fungible-token-transfer/deprecated/README.mdx b/ibc/next/spec/app/ics-020-fungible-token-transfer/deprecated/README.mdx new file mode 100644 index 00000000..27e6ece3 --- /dev/null +++ b/ibc/next/spec/app/ics-020-fungible-token-transfer/deprecated/README.mdx @@ -0,0 +1,841 @@ +--- +ics: 20 +title: Fungible Token Transfer +version: 2 +stage: draft +category: IBC/APP +requires: [25, 26] +kind: instantiation +version_compatibility: null +authors: + - name: Christopher Goes + email: cwgoes@interchain.berlin + - name: Aditya Sripal + email: aditya@interchain.io +created: 2019-07-15 +modified: 2024-03-05 +--- + + +## Synopsis + +This standard document specifies packet data structure, state machine handling logic, and encoding details for the transfer of fungible tokens over an IBC channel between two modules on separate chains. The state machine logic presented allows for safe multi-chain denomination handling with permissionless channel opening. This logic constitutes a "fungible token transfer bridge module", interfacing between the IBC routing module and an existing asset tracking module on the host state machine. + +### Motivation + +Users of a set of chains connected over the IBC protocol might wish to utilise an asset issued on one chain on another chain, perhaps to make use of additional features such as exchange or privacy protection, while retaining fungibility with the original asset on the issuing chain. This application-layer standard describes a protocol for transferring fungible tokens between chains connected with IBC which preserves asset fungibility, preserves asset ownership, limits the impact of Byzantine faults, and requires no additional permissioning. + +### Definitions + +The IBC handler interface & IBC routing module interface are as defined in [ICS 25](../../../core/ics-025-handler-interface) and [ICS 26](../../../core/ics-026-routing-module), respectively. + +### Desired Properties + +- Preservation of fungibility (two-way peg). +- Preservation of total supply (constant or inflationary on a single source chain & module). +- Permissionless token transfers, no need to whitelist connections, modules, or denominations. +- Symmetric (all chains implement the same logic, no in-protocol differentiation of hubs & zones). +- Fault containment: prevents Byzantine-inflation of tokens originating on chain `A`, as a result of chain `B`'s Byzantine behaviour (though any users who sent tokens to chain `B` may be at risk). + +## Technical Specification + +### Data Structures + +Only one packet data type is required: `FungibleTokenPacketData`, which specifies the denomination, amount, sending account, and receiving account or `FungibleTokenPacketDataV2` which specifies multiple tokens being sent between sender and receiver along with an optional forwarding path that can forward tokens further beyond the initial receiving chain. A v2 supporting chain can optionally convert a v1 packet for channels that are still on version 1. + +```typescript +interface FungibleTokenPacketData { + denom: string + amount: uint256 + sender: string + receiver: string + memo: string +} + +interface FungibleTokenPacketDataV2 { + tokens: []Token + sender: string + receiver: string + memo: string + // a struct containing the list of next hops, + // determining where the tokens must be forwarded next, + // and the memo for the final hop + forwarding: Forwarding +} + +interface Token { + denom: Denom + amount: uint256 +} + +interface Denom { + base: string // base denomination + trace: []Hop +} + +interface Forwarding { + hops: []Hop + memo: string +} + +interface Hop { + portId: string + channelId: string +} +``` + +As tokens are sent across chains using the ICS 20 protocol, they begin to accrue a record of channels for which they have been transferred across. This information is encoded into the `trace` field in the token. + +The ICS 20 token traces are represented by a list of `ics20Port` and `ics20Channel` pairs, which are an ICS 20 port and channel on the current chain for which the funds exist. The port and channel pair indicate which channel the funds were previously sent through. Implementations are responsible for correctly parsing the IBC trace information and encoding it into the final on-chain denomination so that the same base denominations sent through different paths are not treated as being fungible. + +A sending chain may be acting as a source or sink zone. When a chain is sending tokens across a port and channel which are not equal to the last prefixed port and channel pair, it is acting as a source zone. When tokens are sent from a source zone, the destination port and channel will be prepended to the trace (once the tokens are received) adding another hop to a tokens record. When a chain is sending tokens across a port and channel which are equal to the last prefixed port and channel pair, it is acting as a sink zone. When tokens are sent from a sink zone, the first element of the trace, which was the last port and channel pair added to the trace is removed (once the tokens are received), undoing the last hop in the tokens record. A more complete explanation is [present in the ibc-go implementation](https://github.com/cosmos/ibc-go/blob/457095517b7832c42ecf13571fee1e550fec02d0/modules/apps/transfer/keeper/relay.go#L18-L49). + +The following sequence diagram exemplifies the multi-chain token transfer dynamics. This process encapsulates the steps involved in transferring tokens in a cycle that begins and ends on the same chain, traversing through chain A, chain B, and chain C. The order of operations is outlined as `A -> B -> C -> A -> C -> B -> A`. + +```mermaid +sequenceDiagram + Note over chain A,chain B: A is source zone: A -> B + chain A->>chain A: Lock (escrow) tokens ("denom") + chain A->>chain B: Send transfer packet with tokens ("denom") + chain B->>chain B: Mint vouchers ("transfer/ChannelToA/denom") + Note over chain B,chain C: B is source zone: B -> C + chain B->>chain B: Lock (escrow) vouchers ("transfer/ChannelToA/denom") + chain B->>chain C: Send transfer packet with vouchers ("transfer/ChannelToA/denom") + chain C->>chain C: Mint vouchers ("transfer/ChannelToB/transfer/ChannelToA/denom") + 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") + 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") + chain C->>chain C: Unlock (unescrow) vouchers ("transfer/ChannelToB/transfer/ChannelToA/denom") + Note over chain B,chain C: C is sink zone: C -> B + chain C->>chain C: Burn vouchers ("transfer/ChannelToB/transfer/ChannelToA/denom") + chain C->>chain B: Send transfer packet with vouchers ("transfer/ChannelToB/transfer/ChannelToA/denom") + chain B->>chain B: Unlock (unescrow) vouchers ("transfer/ChannelToA/denom") + Note over chain B,chain A: B is sink zone: B -> A + chain B->>chain B: Burn vouchers ("transfer/ChannelToB/transfer/ChannelToA/denom") + chain B->>chain A: Send transfer packet with vouchers ("transfer/ChannelToB/transfer/ChannelToA/denom") + chain A->>chain A: Unlock (unescrow) vouchers ("transfer/ChannelToA/denom") +``` + +The forwarding path in the `v2` packet tells the receiving chain where to send the tokens to next. This must be constructed as a list of portID/channelID pairs with each element concatenated as `portID/channelID`. This allows users to automatically route tokens through the interchain. A common usecase might be to unwind the trace of the tokens back to the original source chain before sending it forward to the final intended destination. + +Here are examples of the transfer packet data: + +```typescript + +// V1 example of transfer packet data +FungibleTokenPacketData { + denom: "transfer/channel-1/transfer/channel-4/uatom", + amount: 500, + sender: cosmosexampleaddr1, + receiver: cosmosexampleaddr2, + memo: "exampleMemo", +} + +// V2 example of transfer packet data +FungibleTokenPacketDataV2 { + tokens: [ + Token{ + denom: Denom{ + base: "uatom", + trace: [ + Hop{ + portId: "transfer", + channelId: "channel-1", + }, + Hop{ + portId: "transfer", + channelId: "channel-4", + } + ], + }, + amount: 500, + }, + Token{ + denom: Denom{ + base: "btc", + trace: [ + Hop{ + portId: "transfer", + channelId: "channel-3", + } + ], + }, + amount: 7, + } + ], + sender: cosmosexampleaddr1, + receiver: cosmosexampleaddr2, + memo: "", + forwarding: { + hops: [ + Hop{portId: "transfer", channelId: "channel-7"}, + Hop{portId: "transfer", channelId: "channel-13"}, + ], + memo: "swap: {...}" + }, // provide hops in order and the memo intended for final hop +} +``` + +The acknowledgement data type describes whether the transfer succeeded or failed, and the reason for failure (if any). + +```typescript +type FungibleTokenPacketAcknowledgement = FungibleTokenPacketSuccess | FungibleTokenPacketError; + +interface FungibleTokenPacketSuccess { + // This is binary 0x01 base64 encoded + result: "AQ==" +} + +interface FungibleTokenPacketError { + error: string +} +``` + +Note that both the `FungibleTokenPacketData` as well as `FungibleTokenPacketAcknowledgement` must be JSON-encoded (not Protobuf encoded) when they serialized into packet data. Also note that `uint256` is string encoded when converted to JSON, but must be a valid decimal number of the form `[0-9]+`. + +The fungible token transfer bridge module tracks escrow addresses associated with particular channels in state. Fields of the `ModuleState` are assumed to be in scope. + +```typescript +interface ModuleState { + channelEscrowAddresses: Map + channelForwardingAddresses: Map +} +``` + +### Store paths + +#### Packet forward path + +The `v2` packets that have non-empty forwarding information and should thus be forwarded, must be stored in the private store, so that an acknowledgement can be written for them when receiving an acknowledgement or timeout for the forwarded packet. + +```typescript +function packetForwardPath(portIdentifier: Identifier, channelIdentifier: Identifier, sequence: uint64): Path { + return "forwardedPackets/ports/{portIdentifier}/channels/{channelIdentifier}/sequences/{sequence}" +} +``` + +### Sub-protocols + +The sub-protocols described herein should be implemented in a "fungible token transfer bridge" module with access to a bank module and to the IBC routing module. + +#### Port & channel setup + +The `setup` function must be called exactly once when the module is created (perhaps when the blockchain itself is initialised) to bind to the appropriate port and create an escrow address (owned by the module). + +```typescript +function setup() { + capability = routingModule.bindPort("transfer", ModuleCallbacks{ + onChanOpenInit, + onChanOpenTry, + onChanOpenAck, + onChanOpenConfirm, + onChanCloseInit, + onChanCloseConfirm, + onRecvPacket, + onTimeoutPacket, + onAcknowledgePacket, + onTimeoutPacketClose + }) + claimCapability("port", capability) +} +``` + +Once the `setup` function has been called, channels can be created through the IBC routing module between instances of the fungible token transfer module on separate chains. + +An administrator (with the permissions to create connections & channels on the host state machine) is responsible for setting up connections to other state machines & creating channels +to other instances of this module (or another module supporting this interface) on other chains. This specification defines packet handling semantics only, and defines them in such a fashion +that the module itself doesn't need to worry about what connections or channels might or might not exist at any point in time. + +#### Routing module callbacks + +##### Channel lifecycle management + +Both machines `A` and `B` accept new channels from any module on another machine, if and only if: + +- The channel being created is unordered. +- The version string is `ics20-1` or `ics20-2`. + +```typescript +function onChanOpenInit( + order: ChannelOrder, + connectionHops: [Identifier], + portIdentifier: Identifier, + channelIdentifier: Identifier, + counterpartyPortIdentifier: Identifier, + counterpartyChannelIdentifier: Identifier, + version: string) => (version: string, err: Error) { + // only unordered channels allowed + abortTransactionUnless(order === UNORDERED) + // assert that version is "ics20-1" or "ics20-2" or empty + // if empty, we return the default transfer version to core IBC + // as the version for this channel + abortTransactionUnless(version === "ics20-2" || version === "ics20-1" || version === "") + // allocate an escrow address + channelEscrowAddresses[channelIdentifier] = newAddress(portIdentifier, channelIdentifier) + if version == "" { + // default to latest supported version + return "ics20-2", nil + } + // If the version is not empty and is among those supported, we return the version + return version, nil +} +``` + +```typescript +function onChanOpenTry( + order: ChannelOrder, + connectionHops: [Identifier], + portIdentifier: Identifier, + channelIdentifier: Identifier, + counterpartyPortIdentifier: Identifier, + counterpartyChannelIdentifier: Identifier, + counterpartyVersion: string) => (version: string, err: Error) { + // only unordered channels allowed + abortTransactionUnless(order === UNORDERED) + // assert that version is "ics20-1" or "ics20-2" + abortTransactionUnless(counterpartyVersion === "ics20-1" || counterpartyVersion === "ics20-2") + // allocate an escrow address + channelEscrowAddresses[channelIdentifier] = newAddress(portIdentifier, channelIdentifier) + // return the same version as counterparty version so long as we support it + return counterpartyVersion, nil +} +``` + +```typescript +function onChanOpenAck( + portIdentifier: Identifier, + channelIdentifier: Identifier, + counterpartyChannelIdentifier: Identifier, + counterpartyVersion: string) { + // port has already been validated + // assert that counterparty selected version is the same as our version + channel = provableStore.get(channelPath(portIdentifier, channelIdentifier)) + abortTransactionUnless(counterpartyVersion === channel.version) +} +``` + +```typescript +function onChanOpenConfirm( + portIdentifier: Identifier, + channelIdentifier: Identifier) { + // accept channel confirmations, port has already been validated, version has already been validated +} +``` + +```typescript +function onChanCloseInit( + portIdentifier: Identifier, + channelIdentifier: Identifier) { + // always abort transaction + abortTransactionUnless(FALSE) +} +``` + +```typescript +function onChanCloseConfirm( + portIdentifier: Identifier, + channelIdentifier: Identifier) { + // no action necessary +} +``` + +##### Packet relay + +In plain English, between chains `A` and `B`: + +- When acting as the source zone, the bridge module escrows an existing local asset denomination on the sending chain and mints vouchers on the receiving chain. +- When acting as the sink zone, the bridge module burns local vouchers on the sending chains and unescrows the local asset denomination on the receiving chain. +- When a packet times-out, local assets are unescrowed back to the sender or vouchers minted back to the sender appropriately. +- Acknowledgement data is used to handle failures, such as invalid denominations or invalid destination accounts. Returning + an acknowledgement of failure is preferable to aborting the transaction since it more easily enables the sending chain + to take appropriate action based on the nature of the failure. + +Note: `constructOnChainDenom` is a helper function that will construct the local on-chain denomination for the bridged token. It **must** encode the trace and base denomination to ensure that tokens coming over different paths are not treated as fungible. The original trace and denomination must be retrievable by the state machine so that they can be passed in their original forms when constructing a new IBC path for the bridged token. The ibc-go implementation handles this by creating a local denomination: `hash(trace+base_denom)`. + +`sendFungibleTokens` must be called by a transaction handler in the module which performs appropriate signature checks, specific to the account owner on the host state machine. + +```typescript +function sendFungibleTokens( + tokens: []Token, + sender: string, + receiver: string, + memo: string, + forwarding: Forwarding, + sourcePort: string, + sourceChannel: string, + timeoutHeight: Height, + timeoutTimestamp: uint64, // in unix nanoseconds +): uint64 { + // memo and forwarding cannot both be non-empty + abortTransactionUnless(memo != "" && forwarding != nil) + for token in tokens + onChainDenom = constructOnChainDenom(token.denom.trace, token.denom.base) + // if the token is not prefixed by our channel end's port and channel identifiers + // then we are sending as a source zone + if !isTracePrefixed(sourcePort, sourceChannel, token) { + // determine escrow account + escrowAccount = channelEscrowAddresses[sourceChannel] + // escrow source tokens (assumed to fail if balance insufficient) + bank.TransferCoins(sender, escrowAccount, onChainDenom, token.amount) + } else { + // receiver is source chain, burn vouchers + bank.BurnCoins(sender, onChainDenom, token.amount) + } + } + + var dataBytes bytes + channel = provableStore.get(channelPath(sourcePort, sourceChannel)) + // getAppVersion returns the transfer version that is embedded in the channel version + // as the channel version may contain additional app or middleware version(s) + transferVersion = getAppVersion(channel.version) + if transferVersion == "ics20-1" { + abortTransactionUnless(len(tokens) == 1) + token = tokens[0] + // abort if forwarding defined + abortTransactionUnless(forwarding == nil) + // create v1 denom of the form: port1/channel1/port2/channel2/port3/channel3/denom + v1Denom = constructOnChainDenom(token.denom.trace, token.denom.base) + // v1 packet data does not support forwarding fields + data = FungibleTokenPacketData{v1Denom, token.amount, sender, receiver, memo} + // JSON-marshal packet data into bytes + dataBytes = json.marshal(data) + } else if transferVersion == "ics20-2" { + // create FungibleTokenPacket data + data = FungibleTokenPacketDataV2{tokens, sender, receiver, memo, forwarding} + // protobuf-marshal packet data into bytes + dataBytes = protobuf.marshal(data) + } else { + // should never be reached as transfer version must be negotiated to be either + // ics20-1 or ics20-2 during channel handshake + abortTransactionUnless(false) + } + + // send packet using the interface defined in ICS4 + sequence = handler.sendPacket( + getCapability("port"), + sourcePort, + sourceChannel, + timeoutHeight, + timeoutTimestamp, + dataBytes, + ) + + return sequence +} +``` + +`onRecvPacket` is called by the routing module when a packet addressed to this module has been received. + +Note: Function `parseICS20V1Denom` is a helper function that will take the full IBC denomination and extract the base denomination (i.e. native denomination in the chain of origin) and the trace information (if any) for the received token. + +```typescript +function onRecvPacket(packet: Packet) { + channel = provableStore.get(channelPath(portIdentifier, channelIdentifier)) + // getAppVersion returns the transfer version that is embedded in the channel version + // as the channel version may contain additional app or middleware version(s) + transferVersion = getAppVersion(channel.version) + var tokens []Token + var sender string + var receiver string // address to send tokens to on this chain + var finalReceiver string // final intended address in forwarding case + + if transferVersion == "ics20-1" { + FungibleTokenPacketData data = json.unmarshal(packet.data) + // convert full denom string to denom struct with base denom and trace + denom = parseICS20V1Denom(data.denom) + token = Token{ + denom: denom + amount: data.amount + } + tokens = []Token{token} + sender = data.sender + receiver = data.receiver + } else if transferVersion == "ics20-2" { + FungibleTokenPacketDataV2 data = protobuf.unmarshal(packet.data) + tokens = data.tokens + sender = data.sender + + // if we need to forward the tokens onward + // overwrite the receiver to temporarily send to the + // channel escrow address of the intended receiver + if len(data.forwarding.hops) > 0 { + // memo must be empty + abortTransactionUnless(data.memo == "") + if channelForwardingAddress[packet.destChannel] == "" { + channelForwardingAddress[packet.destChannel] = newAddress() + } + receiver = channelForwardingAddresses[packet.destChannel] + finalReceiver = data.receiver + } else { + receiver = data.receiver + } + } else { + // should never be reached as transfer version must be negotiated + // to be either ics20-1 or ics20-2 during channel handshake + abortTransactionUnless(false) + } + + assert(sender !== "") + assert(receiver !== "") + + // construct default acknowledgement of success + FungibleTokenPacketAcknowledgement ack = FungibleTokenPacketAcknowledgement{true, null} + + receivedTokens = []Token + for token in tokens { + assert(token.denom !== nil) + assert(token.amount > 0) + + var onChainTrace []Hop + // we are the source if the packets were prefixed by the sending chain + // if the sender sends the tokens prefixed with their channel end's + // port and channel identifiers then we are receiving tokens we + // previously had sent to the sender, thus we are receiving the tokens + // as a source zone + if isTracePrefixed(packet.sourcePort, packet.sourceChannel, token) { + // since we are receiving back to source we remove the prefix from the trace + onChainTrace = token.trace[1:] + onChainDenom = constructOnChainDenom(onChainTrace, token.denom.base) + // receiver is source chain: unescrow tokens + // determine escrow account + escrowAccount = channelEscrowAddresses[packet.destChannel] + // unescrow tokens to receiver (assumed to fail if balance insufficient) + err = bank.TransferCoins(escrowAccount, receiver, onChainDenom, token.amount) + if (err != nil) { + ack = FungibleTokenPacketAcknowledgement{false, "transfer coins failed"} + // break out of for loop on first error + break + } + } else { + // since we are receiving to a new sink zone we prepend the prefix to the trace + prefixTrace = Hop{portId: packet.destPort, channelId: packet.destChannel} + onChainTrace = append([]Hop{prefixTrace}, token.denom.trace...) + onChainDenom = constructOnChainDenom(onChainTrace, token.denom.base) + // sender was source, mint vouchers to receiver (assumed to fail if balance insufficient) + err = bank.MintCoins(receiver, onChainDenom, token.amount) + if (err !== nil) { + ack = FungibleTokenPacketAcknowledgement{false, "mint coins failed"} + // break out of for loop on first error + break + } + } + + // add the received token to the received tokens list + recvToken = Token{ + denom: Denom{base: token.denom.base, trace: onChainTrace}, + amount: token.amount, + } + receivedTokens = append(receivedTokens, recvToken) + } + + // if there is an error ack return immediately and do not forward further + if !ack.Success() { + return ack + } + + // if acknowledgement is successful and forwarding path set + // then start forwarding + if len(forwarding.hops) > 0 { + //check that next channel supports token forwarding + channel = provableStore.get(channelPath(forwarding.hops[0].portId, forwarding.hops[0].channelId)) + if channel.version != "ics20-2" && len(forwarding.hops) > 1 { + ack = FungibleTokenPacketAcknowledgement(false, "next hop in path cannot support forwarding onward") + return ack + } + memo = "" + nextForwarding = Forwarding{ + hops: forwarding.hops[1:] + memo: forwarding.memo + } + if len(forwarding.hops) == 1 { + // we're on the last hop, we can set memo and clear + // the next forwarding + memo = forwarding.memo + nextForwarding = nil + } + // send the tokens we received above to the next port and channel + // on the forwarding path + // and reduce the forwarding by the first element + packetSequence = sendFungibleTokens( + receivedTokens, + receiver, // sender of next packet + finalReceiver, // receiver of next packet + memo, + nextForwarding, + forwarding.hops[0].portId, + forwarding.hops[0].channelId, + Height{}, + currentTime() + DefaultHopTimeoutPeriod, + ) + // store packet for future sending ack + privateStore.set(packetForwardPath(forwarding.hops[0].portId, forwarding.hops[0].channelId, packetSequence), packet) + // use async ack until we get successful acknowledgement from further down the line. + return nil + } + + return ack +} +``` + +`onAcknowledgePacket` is called by the routing module when a packet sent by this module has been acknowledged. + +```typescript +function onAcknowledgePacket( + packet: Packet, + acknowledgement: bytes) { + // if the transfer failed, refund the tokens + // to the sender account. In case of a packet sent for a + // forwarded packet, the sender is the forwarding + // address for the destination channel of the forwarded packet. + if !(acknowledgement.success) { + refundTokens(packet) + } + + // check if the packet that was sent is from a previously forwarded packet + prevPacket = privateStore.get(packetForwardPath(packet.sourcePort, packet.sourceChannel, packet.sequence)) + + if prevPacket != nil { + if acknowledgement.success { + FungibleTokenPacketAcknowledgement ack = FungibleTokenPacketAcknowledgement{true, "forwarded packet succeeded"} + handler.writeAcknowledgement( + prevPacket, + ack, + ) + } 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 + revertInFlightChanges(packet, prevPacket) + // write error acknowledgement + FungibleTokenPacketAcknowledgement ack = FungibleTokenPacketAcknowledgement{false, "forwarded packet failed"} + handler.writeAcknowledgement( + prevPacket, + ack, + ) + } + + // delete the forwarded packet that triggered sending this packet + privateStore.delete(packetForwardPath(packet.sourcePort, packet.sourceChannel, packet.sequence)) + } +} +``` + +`onTimeoutPacket` is called by the routing module when a packet sent by this module has timed-out (such that it will not be received on the destination chain). + +```typescript +function onTimeoutPacket(packet: Packet) { + // the packet timed-out, so refund the tokens + // to the sender account. In case of a packet sent for a + // forwarded packet, the sender is the forwarding + // address for the destination channel of the forwarded packet. + refundTokens(packet) + + // check if the packet sent is from a previously forwarded packet + prevPacket = privateStore.get(packetForwardPath(packet.sourcePort, packet.sourceChannel, packet.sequence)) + + 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 + revertInFlightChanges(packet, prevPacket) + // write error acknowledgement + FungibleTokenPacketAcknowledgement ack = FungibleTokenPacketAcknowledgement{false, "forwarded packet timed out"} + handler.writeAcknowledgement( + prevPacket, + ack, + ) + + // delete the forwarded packet that triggered sending this packet + privateStore.delete(packetForwardPath(packet.sourcePort, packet.sourceChannel, packet.sequence)) + } +} +``` + +Given three chains and a transfer from chain A to chain C through chain B, the following diagrams summarize the core logic of the protocol regarding the handling of tokens in the middle chain, both for the success case (i.e. tokens received on chain C) and failure case (i.e. tokens cannot be received on chain C and an error acknowledgement is written): + +![Forwarding success case](/ibc/next/spec/app/ics-020-fungible-token-transfer/deprecated/forwarding-3-chains-success.png) + +![Forwarding failure case](/ibc/next/spec/app/ics-020-fungible-token-transfer/deprecated/forwarding-3-chains-failure.png) + +##### Helper functions + +```typescript +// helper function that returns true if the first element of the trace of the +// token is matches the provided portId and channelId; otherwise it returns false +function isTracePrefixed(portId: string, channelId: string, token: Token) boolean { + trace = token.trace[0] + return trace.portId == portId && trace.channelId == channelId +} +``` + +`refundTokens` is called by both `onAcknowledgePacket`, on failure, and `onTimeoutPacket`, to refund escrowed tokens to the original sender. + +```typescript +function refundTokens(packet: Packet) { + channel = provableStore.get(channelPath(portIdentifier, channelIdentifier)) + // getAppVersion returns the transfer version that is embedded in the channel version + // as the channel version may contain additional app or middleware version(s) + transferVersion = getAppVersion(channel.version) + if transferVersion == "ics20-1" { + FungibleTokenPacketData data = json.unmarshal(packet.data) + // convert full denom string to denom struct with base denom and trace + denom = parseICS20V1Denom(data.denom) + token = Token{ + denom: denom + amount: data.amount + } + tokens = []Token{token} + } else if transferVersion == "ics20-2" { + FungibleTokenPacketDataV2 data = protobuf.unmarshal(packet.data) + tokens = data.tokens + } else { + // should never be reached as transfer version must be negotiated to be either + // ics20-1 or ics20-2 during channel handshake + abortTransactionUnless(false) + } + + for token in tokens { + onChainDenom = constructOnChainDenom(token.denom.trace, token.denom.base) + // Since this is refunding an outgoing packet, we can check if the tokens + // were originally from the receiver by checking if the tokens were prefixed + // by our channel end's identifiers. + if !isTracePrefixed(packet.sourcePort, packet.sourceChannel, token) { + // sender was source chain, unescrow tokens back to sender + escrowAccount = channelEscrowAddresses[packet.sourceChannel] + bank.TransferCoins(escrowAccount, data.sender, onChainDenom, token.amount) + } else { + // receiver was source chain, mint vouchers back to sender + bank.MintCoins(data.sender, onChainDenom, token.amount) + } + } +} +``` + +```typescript +// revertInFlightChanges reverts the receive packet +// that occurs in the middle chains during a packet forwarding +// If an error occurs further down the line, the state changes +// on this chain must be reverted before sending back the error acknowledgement +// to ensure atomic packet forwarding +function revertInFlightChanges(sentPacket: Packet, receivedPacket: Packet) { + forwardingAddress = channelForwardingAddress[receivedPacket.destChannel] + reverseEscrow = channelEscrowAddresses[receivedPacket.destChannel] + + // the token on our chain is the token in the sentPacket + for token in sentPacket.tokens { + // we are checking if the tokens that were sent out by our chain in the + // sentPacket were source tokens with respect to the original receivedPacket. + // If the tokens in sentPacket were prefixed by our channel end's port and channel + // identifiers, then it was a minted voucher and we need to burn it. + // Otherwise, it was an original token from our chain and we must give the tokens + // back to the escrow account. + if !isTracePrefixed(receivedPacket.destinationPort, receivedPacket.destinationChannel, token) { + // receive sent tokens from the received escrow account to the forwarding account + // so we must send the tokens back from the forwarding account to the received escrow account + bank.TransferCoins(forwardingAddress, reverseEscrow, token.denom, token.amount) + } else { + // receive minted vouchers and sent to the forwarding account + // so we must burn the vouchers from the forwarding account + bank.BurnCoins(forwardingAddress, token.denom, token.amount) + } + } +} +``` + +```typescript +function onTimeoutPacketClose(packet: Packet) { + // can't happen, only unordered channels allowed +} +``` + +#### Using the Memo Field + +Note: Since earlier versions of this specification did not include a `memo` field, implementations must ensure that the new packet data is still compatible with chains that expect the old packet data. A legacy implementation MUST be able to unmarshal a new packet data with an empty string memo into the legacy `FungibleTokenPacketData` struct. Similarly, an implementation supporting `memo` must be able to unmarshal a legacy packet data into the current struct with the `memo` field set to the empty string. + +The `memo` field is not used within transfer, however it may be used either for external off-chain users (i.e. exchanges) or for middleware wrapping transfer that can parse and execute custom logic on the basis of the passed in memo. If the memo is intended to be parsed and interpreted by higher-level middleware, then these middleware are advised to namespace their additions to the memo string so that they do not overwrite each other. Chains should ensure that there is some length limit on the entire packet data to ensure that the packet does not become a DOS vector. However, these do not need to be protocol-defined limits. If the receiver cannot accept a packet because of length limitations, this will lead to a timeout on the sender side. + +Memos that are intended to be read by higher level middleware for custom execution must be structured so that different middleware can read relevant data in the memo intended for them without interfering with data intended for other middlewares. + +Thus, for any memo that is meant to be interpreted by the state machine; it is recommended that the memo is a JSON object with each middleware reserving a key that it can read into and retrieve relevant data. This way the memo can be constructed to pass in information such that multiple middleware can read the memo without interference from each other. + +Example: + +```json +{ + "wasm": { + "address": "contractAddress", + "arguments": "marshalledArguments", + }, + "callback": "contractAddress", + "router": "routerArgs", +} +``` + +Here, the "wasm", "callback", and "router" fields are all intended for separate middlewares that will exclusively read those fields respectively in order to execute their logic. This allows multiple modules to read from the memo. Middleware should take care to reserve a unique key so that they do not accidentally read data intended for a different module. This issue can be avoided by some off-chain registry of keys already in-use in the JSON object. + +#### Reasoning + +##### Correctness + +This implementation preserves both fungibility & supply. + +Fungibility: If tokens have been sent to the counterparty chain, they can be redeemed back in the same denomination & amount on the source chain. + +Supply: Redefine supply as unlocked tokens. All send-recv pairs sum to net zero. Source chain can change supply. + +##### Multi-chain notes + +This specification does not directly handle the "diamond problem", where a user sends a token originating on chain A to chain B, then to chain D, and wants to return it through D -> C -> A — since the supply is tracked as owned by chain B (and the denomination will be "{portOnD}/{channelOnD}/{portOnB}/{channelOnB}/denom"), chain C cannot serve as the intermediary. It is not yet clear whether that case should be dealt with in-protocol or not — it may be fine to just require the original path of redemption (and if there is frequent liquidity and some surplus on both paths the diamond path will work most of the time). Complexities arising from long redemption paths may lead to the emergence of central chains in the network topology. + +In order to track all of the denominations moving around the network of chains in various paths, it may be helpful for a particular chain to implement a registry which will track the "global" source chain for each denomination. End-user service providers (such as wallet authors) may want to integrate such a registry or keep their own mapping of canonical source chains and human-readable names in order to improve UX. + +#### Optional addenda + +- Each chain, locally, could elect to keep a lookup table to use short, user-friendly local denominations in state which are translated to and from the longer denominations when sending and receiving packets. +- Additional restrictions may be imposed on which other machines may be connected to & which channels may be established. + +## Backwards Compatibility + +Not applicable. + +## Forwards Compatibility + +This initial standard uses version "ics20-1" in the channel handshake. + +A future version of this standard could use a different version in the channel handshake, +and safely alter the packet data format & packet handler semantics. + +## Example Implementations + +- Implementation of ICS 20 in Go can be found in [ibc-go repository](https://github.com/cosmos/ibc-go). +- Implementation of ICS 20 in Rust can be found in [ibc-rs repository](https://github.com/cosmos/ibc-rs). + +## History + +Jul 15, 2019 - Draft written + +Jul 29, 2019 - Major revisions; cleanup + +Aug 25, 2019 - Major revisions, more cleanup + +Feb 3, 2020 - Revisions to handle acknowledgements of success & failure + +Feb 24, 2020 - Revisions to infer source field, inclusion of version string + +July 27, 2020 - Re-addition of source field + +Nov 11, 2022 - Addition of a memo field + +Sep 22, 2023 - [Support for multi-token packets](https://github.com/cosmos/ibc/pull/1020) + +March 5, 2024 - [Support for path forwarding](https://github.com/cosmos/ibc/pull/1090) + +June 18, 2024 - [Support for data protobuf encoding](https://github.com/cosmos/ibc/pull/1118) + +## Copyright + +All content herein is licensed under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0). diff --git a/ibc/next/spec/app/ics-020-fungible-token-transfer/deprecated/forwarding-3-chains-failure.png b/ibc/next/spec/app/ics-020-fungible-token-transfer/deprecated/forwarding-3-chains-failure.png new file mode 100644 index 0000000000000000000000000000000000000000..36eccc1d32d6b411f462f036dd3d280e72f58281 GIT binary patch literal 286335 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

<>muTyAHd$f2fXF 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�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%0DfGhoS)rK!^^OGH;! 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�J*wD=8>vM|$X4FNmDSDpLF&WxX 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

qkNSy=mK&8k(8mR{v8ReJQuKVx2zv!Wt^3g;)* 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�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 literal 0 HcmV?d00001 diff --git a/ibc/next/spec/app/ics-020-fungible-token-transfer/deprecated/forwarding-3-chains-success.png b/ibc/next/spec/app/ics-020-fungible-token-transfer/deprecated/forwarding-3-chains-success.png new file mode 100644 index 0000000000000000000000000000000000000000..3229fbb3ff76f4e4a866a12817f64618402c1680 GIT binary patch literal 231425 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

l}-dZ{`B!90* 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

<6v|k^*9-$8w{)JF?a3t;@LYeral% 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 interchain account address. See [metadata negotiation](#metadata-negotiation) section below for how to implement this. +6. During the `OnChanOpenAck` & `OnChanOpenConfirm` callbacks on the controller & host chains respectively, the [active-channel](#active-channels) for this interchain account/owner pair, is set in state. + +#### Active channels + +The controller and host chain must keep track of an `active-channel` for each registered interchain account. The `active-channel` is set during the channel creation handshake process. This is a safety mechanism that allows a controller chain to regain access to an interchain account on a host chain in case of a channel closing. + +An example of an active channel on the controller chain can look like this: + +```typescript +{ + // Controller Chain + SourcePortId: `icacontroller-`, + SourceChannelId: ``, + // Host Chain + CounterpartyPortId: `icahost`, + CounterpartyChannelId: ``, +} +``` + +In the event of a channel closing, the active channel may be replaced by starting a new channel handshake with the same port identifiers on the same underlying connection of the original active channel. ICS-27 channels can only be closed in the event of a timeout (if the implementation uses ordered channels) or in the unlikely event of a light client attack. Controller chains must retain the ability to open new ICS-27 channels and reset the active channel for a particular portID (containing `{owner-account-address}`) and connectionID pair. + +The controller and host chains must verify that any new channel maintains the same metadata as the previous active channel to ensure that the parameters of the interchain account remain the same even after replacing the active channel. The `Address` of the metadata should not be verified since it is expected to be empty at the INIT stage, and the host chain will regenerate the exact same address on TRY, because it is expected to generate the interchain account address deterministically from the controller portID and connectionID (both of which must remain the same). + +#### **Metadata negotiation** + +ICS-27 takes advantage of [ICS-04 channel version negotiation](/ibc/next/spec/core/ics-004-channel-and-packet-semantics/README) to negotiate metadata and channel parameters during the channel handshake. The metadata will contain the encoding format along with the transaction type so that the counterparties can agree on the structure and encoding of the interchain transactions. The metadata sent from the host chain on the TRY step will also contain the interchain account address, so that it can be relayed to the controller chain. At the end of the channel handshake, both the controller and host chains will store a mapping of (controller chain portID, controller/host connectionID) to the newly registered interchain account address ([account registration flow](#register-account-flow)). + +ICS-04 allows for each channel version negotiation to be application-specific. In the case of interchain accounts, the channel version will be a string of a JSON struct containing all the relevant metadata intended to be relayed to the counterparty during the channel handshake step ([see summary below](#metadata-negotiation-summary)). + +Combined with the one channel per interchain account approach, this method of metadata negotiation allows us to pass the address of the interchain account back to the controller chain and create a mapping from (controller portID, controller connection ID) -> interchain account address during the `OnChanOpenAck` callback. As outlined in the [controlling flow](#controlling-flow), a controller chain will need to know the address of a registered interchain account in order to send transactions to the account on the host chain. + +#### **Metadata negotiation summary** + +`interchain-account-address` is the address of the interchain account registered on the host chain by the controller chain. + +- **INIT** + +Initiator: Controller + +Datagram: ChanOpenInit + +Chain Acted Upon: Controller + +Version: + +```json +{ + "Version": "ics27-1", + "ControllerConnectionId": "self_connection_id", + "HostConnectionId": "counterparty_connection_id", + "Address": "", + "Encoding": "requested_encoding_type", + "TxType": "requested_tx_type", +} +``` + +Comments: The address is left empty since this will be generated and relayed back by the host chain. The connection identifiers must be included to ensure that if a new channel needs to be opened (in case active channel times out), then we can ensure that the new channel is opened on the same connection. This will ensure that the interchain account is always connected to the same counterparty chain. + +- **TRY** + +Initiator: Relayer + +Datagram: ChanOpenTry + +Chain Acted Upon: Host + +Version: + +```json +{ + "Version": "ics27-1", + "ControllerConnectionId": "counterparty_connection_id", + "HostConnectionId": "self_connection_id", + "Address": "interchain_account_address", + "Encoding": "negotiated_encoding_type", + "TxType": "negotiated_tx_type", +} +``` + +Comments: The ICS-27 application on the host chain is responsible for returning this version given the counterparty version set by the controller chain in INIT. The host chain must agree with the single encoding type and a single tx type that is requested by the controller chain (ie. included in counterparty version). If the requested encoding or tx type is not supported, then the host chain must return an error and abort the handshake. +The host chain must also generate the interchain account address and populate the address field in the version with the interchain account address string. + +- **ACK** + +Initiator: Relayer + +Datagram: ChanOpenAck + +Chain Acted Upon: Controller + +CounterpartyVersion: + +```json +{ + "Version": "ics27-1", + "ControllerConnectionId": "self_connection_id", + "HostConnectionId": "counterparty_connection_id", + "Address": "interchain_account_address", + "Encoding": "negotiated_encoding_type", + "TxType": "negotiated_tx_type", +} +``` + +Comments: On the ChanOpenAck step, the ICS27 application on the controller chain must verify the version string chosen by the host chain on ChanOpenTry. The controller chain must verify that it can support the negotiated encoding and tx type selected by the host chain. If either is unsupported, then it must return an error and abort the handshake. +If both are supported, then the controller chain must store a mapping from the channel's portID to the provided interchain account address and return successfully. + +#### Controlling flow + +Once an interchain account is registered on the host chain a controller chain can begin sending instructions (messages) to the host chain to control the account. + +1. The controller chain calls `SendTx` and passes message(s) that will be executed on the host side by the associated interchain account (determined by the controller side port identifier) + +Cosmos SDK pseudo-code example: + +```golang +// connectionId is the identifier for the controller connection +interchainAccountAddress := GetInterchainAccountAddress(portId, connectionId) +msg := &banktypes.MsgSend{FromAddress: interchainAccountAddress, ToAddress: ToAddress, Amount: amount} +icaPacketData = InterchainAccountPacketData{ + Type: types.EXECUTE_TX, + Data: serialize(msg), + Memo: "memo", +} + +// Sends the message to the host chain, where it will eventually be executed +SendTx(ownerAddress, connectionId, portID, data, timeout) +``` + +2. The host chain upon receiving the IBC packet will call `DeserializeTx`. + +3. The host chain will then call `AuthenticateTx` and `ExecuteTx` for each message and return an acknowledgment containing a success or error. + +Messages are authenticated on the host chain by taking the controller side port identifier and calling `GetInterchainAccountAddress(controllerPortId, hostConnectionId)` to get the expected interchain account address for the current controller port and connection identifier. If the signer of this message does not match the expected account address then authentication will fail. + +### Packet Data + +`InterchainAccountPacketData` contains an array of messages that an interchain account can execute and a memo string that is sent to the host chain as well as the packet `type`. ICS-27 version 1 has only one type `EXECUTE_TX`. + +```proto +message InterchainAccountPacketData { + enum type + bytes data = 1; + string memo = 2; +} +``` + +The acknowledgment packet structure is defined as in [ics4](https://github.com/cosmos/ibc-go/blob/main/proto/ibc/core/channel/v1/channel.proto#L135-L148). If an error occurs on the host chain the acknowledgment contains the error message. + +```proto +message Acknowledgement { + // response contains either a result or an error and must be non-empty + oneof response { + bytes result = 21; + string error = 22; + } +} +``` + +### Custom logic + +ICS-27 relies on [ICS-30 middleware architecture](../ics-030-middleware) to provide the option for application developers to apply custom logic on the success or fail of ICS-27 packets. + +Controller chains will wrap `OnAcknowledgementPacket` & `OnTimeoutPacket` to handle the success or fail cases for ICS-27 packets. + +### Port & channel setup + +The interchain account module on a host chain must always bind to a port with the id `icahost`. Controller chains will bind to ports dynamically, as specified in the identifier format [section](#identifier-formats). + +The example below assumes a module is implementing the entire `InterchainAccountModule` interface. The `setup` function must be called exactly once when the module is created (perhaps when the blockchain itself is initialized) to bind to the appropriate port. + +```typescript +function setup() { + capability = routingModule.bindPort("icahost", ModuleCallbacks{ + onChanOpenInit, + onChanOpenTry, + onChanOpenAck, + onChanOpenConfirm, + onChanCloseInit, + onChanCloseConfirm, + onChanUpgradeInit, // read-only + onChanUpgradeTry, // read-only + onChanUpgradeAck, // read-only + onChanUpgradeOpen, + onRecvPacket, + onTimeoutPacket, + onAcknowledgePacket, + onTimeoutPacketClose + }) + claimCapability("port", capability) +} +``` + +Once the `setup` function has been called, channels can be created via the IBC routing module. + +### Channel lifecycle management + +An interchain account module will accept new channels from any module on another machine, if and only if the channel initialization step is being invoked from the controller chain. + +```typescript +// Called on Controller Chain by InitInterchainAccount +function onChanOpenInit( + order: ChannelOrder, + connectionHops: [Identifier], + portIdentifier: Identifier, + channelIdentifier: Identifier, + counterpartyPortIdentifier: Identifier, + counterpartyChannelIdentifier: Identifier, + version: string +): (version: string, err: Error) { + // validate port format + abortTransactionUnless(validateControllerPortParams(portIdentifier)) + // only allow channels to be created on the "icahost" port on the counterparty chain + abortTransactionUnless(counterpartyPortIdentifier === "icahost") + + // retrieve channel and connection to access connection ID and counterparty connection ID + channel = provableStore.get(channelPath(portIdentifier, channelIdentifier)) + connectionId = channel.connectionHops[0] + connection = provableStore.get(connectionPath(connectionId)) + + if version != "" { + // validate metadata + metadata = UnmarshalJSON(version) + abortTransactionUnless(metadata.Version === "ics27-1") + // all elements in encoding list and tx type list must be supported + abortTransactionUnless(IsSupportedEncoding(metadata.Encoding)) + abortTransactionUnless(IsSupportedTxType(metadata.TxType)) + abortTransactionUnless(metadata.ControllerConnectionId === connectionId) + abortTransactionUnless(metadata.HostConnectionId === connection.counterpartyConnectionIdentifier) + } else { + // construct default metadata + metadata = { + Version: "ics27-1", + ControllerConnectionId: connectionId, + HostConnectionId: counterpartyConnectionId, + // implementation may choose a default encoding and TxType + // e.g. DefaultEncoding=protobuf, DefaultTxType=sdk.MultiMsg + Encoding: DefaultEncoding, + TxType: DefaultTxType, + } + version = marshalJSON(metadata) + } + + // only open the channel if: + // - there is no active channel already set (with status OPEN) + // OR + // - there is already an active channel (with status CLOSED) AND + // the metadata matches exactly the existing metadata in the + // version string of the active channel AND the ordering of the + // new channel matches the ordering of the active channel. + activeChannelId, activeChannelFound = GetActiveChannelID(portId, connectionId) + if activeChannelFound { + activeChannel = provableStore.get(channelPath(portId, activeChannelId)) + abortTransactionUnless(channel !== null) + abortTransactionUnless(activeChannel.state === CLOSED) + previousOrder = activeChannel.order + abortTransactionUnless(previousOrder === order) + previousMetadata = UnmarshalJSON(activeChannel.version) + abortTransactionUnless(previousMetadata === metadata) + } + + return version, nil +} +``` + +```typescript +// Called on Host Chain by Relayer +function onChanOpenTry( + order: ChannelOrder, + connectionHops: [Identifier], + portIdentifier: Identifier, + channelIdentifier: Identifier, + counterpartyPortIdentifier: Identifier, + counterpartyChannelIdentifier: Identifier, + counterpartyVersion: string +): (version: string, err: Error) { + // validate port ID + abortTransactionUnless(portIdentifier === "icahost") + + // retrieve channel and connection to access connection ID and counterparty connection ID + channel = provableStore.get(channelPath(portIdentifier, channelIdentifier)) + connectionId = channel.connectionHops[0] + connection = provableStore.get(connectionPath(connectionId)) + + // create the interchain account with the counterpartyPortIdentifier + // and the underlying connectionID on the host chain. + address = RegisterInterchainAccount(counterpartyPortIdentifier, connectionId) + + // state change to keep track of successfully registered interchain account + SetInterchainAccountAddress(counterpartyPortIdentifier, connectionId, address) + + cpMetadata = UnmarshalJSON(counterpartyVersion) + // it's not mandatory for the controller to fill in the host connection ID, since + // it could not be possible for it to know it. ibc-go's implementation of the + // controller does fill it in, but an CosmWasm controller implementation would + // not be able. For that reason, the host fills in here its own connection ID. + cpMetadata.HostConnectionId = connectionId + + abortTransactionUnless(cpMetadata.Version === "ics27-1") + // If encoding or txType requested by initializing chain is not supported by host chain then + // fail handshake and abort transaction + abortTransactionUnless(IsSupportedEncoding(cpMetadata.Encoding)) + abortTransactionUnless(IsSupportedTxType(cpMetadata.TxType)) + abortTransactionUnless(cpMetadata.ControllerConnectionId === connection.counterpartyConnectionIdentifier) + abortTransactionUnless(cpMetadata.HostConnectionId === connectionId) + + metadata = { + "Version": "ics27-1", + "ControllerConnectionId": cpMetadata.ControllerConnectionId, + "HostConnectionId": cpMetadata.HostConnectionId, + "Address": address, + "Encoding": cpMetadata.Encoding, + "TxType": cpMetadata.TxType, + } + + return string(MarshalJSON(metadata)), nil +} +``` + +```typescript +// Called on Controller Chain by Relayer +function onChanOpenAck( + portIdentifier: Identifier, + channelIdentifier: Identifier, + counterpartyChannelIdentifier, + counterpartyVersion: string +) { + // retrieve channel and connection to access connection ID and counterparty connection ID + channel = provableStore.get(channelPath(portIdentifier, channelIdentifier)) + connectionId = channel.connectionHops[0] + connection = provableStore.get(connectionPath(connectionId)) + + // validate counterparty metadata decided by host chain + metadata = UnmarshalJSON(version) + abortTransactionUnless(metadata.Version === "ics27-1") + abortTransactionUnless(IsSupportedEncoding(metadata.Encoding)) + abortTransactionUnless(IsSupportedTxType(metadata.TxType)) + abortTransactionUnless(metadata.ControllerConnectionId === connectionId) + abortTransactionUnless(metadata.HostConnectionId === connection.counterpartyConnectionIdentifier) + + // state change to keep track of successfully registered interchain account + SetInterchainAccountAddress(portID, metadata.ControllerConnectionId, metadata.Address) + // set the active channel for this owner/interchain account pair + SetActiveChannelID(portIdentifier, metadata.ControllerConnectionId, channelIdentifier) +} +``` + +```typescript +// Called on Host Chain by Relayer +function onChanOpenConfirm( + portIdentifier: Identifier, + channelIdentifier: Identifier +) { + channel = provableStore.get(channelPath(portIdentifier, channelIdentifier)) + abortTransactionUnless(channel !== null) + + // set the active channel for this owner/interchain account pair + SetActiveChannelID(channel.counterpartyPortIdentifier, channel.connectionHops[0], channelIdentifier) +} +``` + +```typescript +// The controller portID must have the format: `icacontroller-{ownerAddress}` +function validateControllerPortParams(portIdentifier: Identifier) { + split(portIdentifier, "-") + abortTransactionUnless(portIdentifier[0] === "icacontroller") + abortTransactionUnless(IsValidAddress(portIdentifier[1])) +} +``` + +### Closing handshake + +```typescript +function onChanCloseInit( + portIdentifier: Identifier, + channelIdentifier: Identifier) { + // disallow user-initiated channel closing for interchain account channels + abortTransactionUnless(FALSE) +} +``` + +```typescript +function onChanCloseConfirm( + portIdentifier: Identifier, + channelIdentifier: Identifier) { +} +``` + +### Upgrade handshake + +```typescript +// Called on Controller Chain by Authority +function onChanUpgradeInit( + portIdentifier: Identifier, + channelIdentifier: Identifier, + order: ChannelOrder, + connectionHops: [Identifier], + upgradeSequence: uint64, + version: string +): (version: string, err: Error) { + // new version proposed in the upgrade + abortTransactionUnless(version !== "") + metadata = UnmarshalJSON(version) + + // retrieve the existing channel version. + // In ibc-go, for example, this is done using the GetAppVersion + // function of the ICS4Wrapper interface. + // See https://github.com/cosmos/ibc-go/blob/ac6300bd857cd2bd6915ae51e67c92848cbfb086/modules/core/05-port/types/module.go#L128-L132 + channel = provableStore.get(channelPath(portIdentifier, channelIdentifier)) + abortTransactionUnless(channel !== null) + currentMetadata = UnmarshalJSON(channel.version) + + // validate metadata + abortTransactionUnless(metadata.Version === "ics27-1") + // all elements in encoding list and tx type list must be supported + abortTransactionUnless(IsSupportedEncoding(metadata.Encoding)) + abortTransactionUnless(IsSupportedTxType(metadata.TxType)) + + // the interchain account address on the host chain + // must remain the same after the upgrade. + abortTransactionUnless(currentMetadata.Address === metadata.Address) + + // at the moment it is not supported to perform upgrades that + // change the connection ID of the controller or host chains. + // therefore these connection IDs much remain the same as before. + abortTransactionUnless(currentMetadata.ControllerConnectionId === metadata.ControllerConnectionId) + abortTransactionUnless(currentMetadata.HostConnectionId === metadata.HostConnectionId) + // the proposed connection hop must not change + abortTransactionUnless(currentMetadata.ControllerConnectionId === connectionHops[0]) + + return version, nil +} +``` + +```typescript +// Called on Host Chain by Relayer +function onChanUpgradeTry( + portIdentifier: Identifier, + channelIdentifier: Identifier, + order: ChannelOrder, + connectionHops: [Identifier], + upgradeSequence: uint64, + counterpartyPortIdentifier: Identifier, + counterpartyChannelIdentifier: Identifier, + counterpartyVersion: string +): (version: string, err: Error) { + // validate port ID + abortTransactionUnless(portIdentifier === "icahost") + + // upgrade version proposed by counterparty + abortTransactionUnless(counterpartyVersion !== "") + metadata = UnmarshalJSON(counterpartyVersion) + + // retrieve the existing channel version. + // In ibc-go, for example, this is done using the GetAppVersion + // function of the ICS4Wrapper interface. + // See https://github.com/cosmos/ibc-go/blob/ac6300bd857cd2bd6915ae51e67c92848cbfb086/modules/core/05-port/types/module.go#L128-L132 + channel = provableStore.get(channelPath(portIdentifier, channelIdentifier)) + abortTransactionUnless(channel !== null) + currentMetadata = UnmarshalJSON(channel.version) + + // validate metadata + abortTransactionUnless(metadata.Version === "ics27-1") + // all elements in encoding list and tx type list must be supported + abortTransactionUnless(IsSupportedEncoding(metadata.Encoding)) + abortTransactionUnless(IsSupportedTxType(metadata.TxType)) + + // the interchain account address on the host chain + // must remain the same after the upgrade. + abortTransactionUnless(currentMetadata.Address === metadata.Address) + + // at the moment it is not supported to perform upgrades that + // change the connection ID of the controller or host chains. + // therefore these connection IDs much remain the same as before. + abortTransactionUnless(currentMetadata.ControllerConnectionId === metadata.ControllerConnectionId) + abortTransactionUnless(currentMetadata.HostConnectionId === metadata.HostConnectionId) + // the proposed connection hop must not change + abortTransactionUnless(currentMetadata.HostConnectionId === connectionHops[0]) + + return counterpartyVersion, nil +} +``` + +```typescript +// Called on Controller Chain by Relayer +function onChanUpgradeAck( + portIdentifier: Identifier, + channelIdentifier: Identifier, + counterpartyVersion: string +): Error { + // final upgrade version proposed by counterparty + abortTransactionUnless(counterpartyVersion !== "") + metadata = UnmarshalJSON(counterpartyVersion) + + // retrieve the existing channel version. + // In ibc-go, for example, this is done using the GetAppVersion + // function of the ICS4Wrapper interface. + // See https://github.com/cosmos/ibc-go/blob/ac6300bd857cd2bd6915ae51e67c92848cbfb086/modules/core/05-port/types/module.go#L128-L132 + channel = provableStore.get(channelPath(portIdentifier, channelIdentifier)) + abortTransactionUnless(channel !== null) + currentMetadata = UnmarshalJSON(channel.version) + + // validate metadata + abortTransactionUnless(metadata.Version === "ics27-1") + // all elements in encoding list and tx type list must be supported + abortTransactionUnless(IsSupportedEncoding(metadata.Encoding)) + abortTransactionUnless(IsSupportedTxType(metadata.TxType)) + + // the interchain account address on the host chain + // must remain the same after the upgrade. + abortTransactionUnless(currentMetadata.Address === metadata.Address) + + // at the moment it is not supported to perform upgrades that + // change the connection ID of the controller or host chains. + // therefore these connection IDs much remain the same as before. + abortTransactionUnless(currentMetadata.ControllerConnectionId === metadata.ControllerConnectionId) + abortTransactionUnless(currentMetadata.HostConnectionId === metadata.HostConnectionId) + + return nil +} +``` + +```typescript +// Called on Controller and Host Chains by Relayer +function onChanUpgradeOpen( + portIdentifier: Identifier, + channelIdentifier: Identifier) { + // no-op +} +``` + +### Packet relay + +`onRecvPacket` is called by the routing module when a packet addressed to this module has been received. + +```typescript +// Called on Host Chain by Relayer +function onRecvPacket(packet Packet) { + ack = NewResultAcknowledgement([]byte{byte(1)}) + + // only attempt the application logic if the packet data + // was successfully decoded + switch data.Type { + case types.EXECUTE_TX: + msgs, err = types.DeserializeTx(data.Data) + if err != nil { + return NewErrorAcknowledgement(err) + } + + // ExecuteTx calls the AuthenticateTx function defined above + result, err = ExecuteTx(ctx, packet.sourcePort, packet.destPort, packet.destChannel, msgs) + if err != nil { + // NOTE: The error string placed in the acknowledgement must be consistent across all + // nodes in the network or there will be a fork in the state machine. + return NewErrorAcknowledgement(err) + } + + // return acknowledgement containing the transaction result after executing on host chain + return NewAcknowledgement(result) + + default: + return NewErrorAcknowledgement(ErrUnknownDataType) + } +} +``` + +`onAcknowledgePacket` is called by the routing module when a packet sent by this module has been acknowledged. + +```typescript +// Called on Controller Chain by Relayer +function onAcknowledgePacket( + packet: Packet, + acknowledgement: bytes +) { + // call underlying app's OnAcknowledgementPacket callback + // see ICS-30 middleware for more information +} +``` + +```typescript +// Called on Controller Chain by Relayer +function onTimeoutPacket(packet: Packet) { + // call underlying app's OnTimeoutPacket callback + // see ICS-30 middleware for more information +} +``` + +Note that interchain accounts controller modules should not execute any logic upon packet receipt, i.e. the `OnRecvPacket` callback should not be called, and in case it is called, it should simply return an error acknowledgement: + +```typescript +// Called on Controller Chain by Relayer +function onRecvPacket(packet Packet) { + return NewErrorAcknowledgement(ErrInvalidChannelFlow) +} +``` + +### Identifier formats + +These are the default formats that the port identifiers on each side of an interchain accounts channel. The controller portID **must** include the owner address so that when a message is sent to the controller module, the sender of the message can be verified against the portID before sending the ICA packet. The controller chain is responsible for proper access control to ensure that the sender of the ICA message has successfully authenticated before the message reaches the controller module. + +Controller Port Identifier: optional prefix `icacontroller-` + mandatory `{owner-account-address}` + +Host Port Identifier: `icahost` + +The `icacontroller-` prefix on the controller port identifier is optional and host chains **must** not enforce that the counterparty port identifier includes it. Controller chains may decide to include it and validate that it is present in their own port identifier. + +## Example Implementations + +- Implementation of ICS 27 in Go can be found in [ibc-go repository](https://github.com/cosmos/ibc-go). + +## Future Improvements + +A future version of interchain accounts may be greatly simplified by the introduction of an IBC channel type that is ORDERED but does not close the channel on timeouts, and instead proceeds to accept and receive the next packet. If such a channel type is made available by core IBC, Interchain accounts could require the use of this channel type and remove all logic and state pertaining to "active channels". The metadata format can also be simplified to remove any reference to the underlying connection identifiers. + +The "active channel" setting and unsetting is currently necessary to allow interchain account owners to create a new channel in case the current active channel closes during channel timeout. The connection identifiers are part of the metadata to ensure that any new channel that gets opened are established on top of the original connection. All of this logic becomes unnecessary once the channel is ordered **and** unclosable, which can only be achieved by the introduction of a new channel type to core IBC. + +## History + +Aug 1, 2019 - Concept discussed + +Sep 24, 2019 - Draft suggested + +Nov 8, 2019 - Major revisions + +Dec 2, 2019 - Minor revisions (Add more specific description & Add interchain account on Ethereum) + +July 14, 2020 - Major revisions + +April 27, 2021 - Redesign of ics27 specification + +November 11, 2021 - Update with latest changes from implementation + +December 14, 2021 - Revisions to spec based on audits and maintainer reviews + +August 1, 2023 - Implemented channel upgrades callbacks + +## Copyright + +All content herein is licensed under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0). diff --git a/ibc/next/spec/app/ics-028-cross-chain-validation/README.mdx b/ibc/next/spec/app/ics-028-cross-chain-validation/README.mdx new file mode 100644 index 00000000..6e43c8cf --- /dev/null +++ b/ibc/next/spec/app/ics-028-cross-chain-validation/README.mdx @@ -0,0 +1,74 @@ +--- +ics: 28 +title: Cross-Chain Validation +stage: draft +category: IBC/APP +requires: [25, 26, 20] +authors: + - name: Marius Poke + email: marius@informal.systems + - name: Aditya Sripal + email: aditya@interchain.io + - name: Jovan Komatovic + email: jovan.komatovic@epfl.ch + - name: Cezara Dragoi + email: cezara.dragoi@inria.fr + - name: Josef Widder + email: josef@informal.systems +created: 2022-06-27 +modified: 2022-12-02 +--- + +# Synopsis + +This standard document specifies packet data structure, state machine handling logic, and encoding details for Cross-Chain Validation (CCV). CCV is the specific IBC level protocol that enables *Interchain Security*, a Cosmos-specific category of *Shared Security*. + +At a high level, CCV enables a *provider chain* (e.g., the Cosmos Hub) to provide *security* to multiple *consumer chains*. This means that the validator sets on the consumer chains are chosen from the validator set of the provider chain (for more details, see the [Security Model](/ibc/next/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts#security-model) section). + +The communication between the provider and the consumer chains is done through the IBC protocol over a *unique*, *ordered* channel (one for each consumer chain). + +> Throughout this document, we will use the terms chain and blockchain interchangeably. + +## Contents + +- [Overview and Basic Concepts](/ibc/next/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts) +- [System Model and Properties](/ibc/next/spec/app/ics-028-cross-chain-validation/system_model_and_properties) +- [Technical Specification: Data Structures and Methods](/ibc/next/spec/app/ics-028-cross-chain-validation/technical_specification) + - [Data Structures](/ibc/next/spec/app/ics-028-cross-chain-validation/data_structures) + - [Methods](/ibc/next/spec/app/ics-028-cross-chain-validation/methods) + +{/* +## Backwards Compatibility + +(discussion of compatibility or lack thereof with previous standards) + +## Forwards Compatibility + +*/} + +## Example Implementations + +- Interchain Security [Go implementation](https://github.com/cosmos/interchain-security). + +{/* +## Other Implementations + +(links to or descriptions of other implementations) + +*/} + +## History + +Jun 27, 2022 - Draft written + +Aug 3, 2022 - Revision of *Bond-Based Consumer Voting Power* property + +Aug 29, 2022 - Notify Staking module of matured unbondings in `EndBlock()` + +Dec 2, 2022 - Enable existing chains to become consumer chains + +Dec 7, 2022 - Add provider-based timeouts + +## Copyright + +All content herein is licensed under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0). diff --git a/ibc/next/spec/app/ics-028-cross-chain-validation/data_structures.mdx b/ibc/next/spec/app/ics-028-cross-chain-validation/data_structures.mdx new file mode 100644 index 00000000..61bd92bd --- /dev/null +++ b/ibc/next/spec/app/ics-028-cross-chain-validation/data_structures.mdx @@ -0,0 +1,340 @@ +--- +title: "CCV: Technical Specification - Data Structures" +--- + +{/* omit in toc */} + +{/* omit in toc */} +## Outline + +- [External Data Structures](#external-data-structures) +- [CCV Data Structures](#ccv-data-structures) +- [CCV Packets](#ccv-packets) +- [CCV State](#ccv-state) + - [State on Provider Chain](#state-on-provider-chain) + - [State on Consumer Chain](#state-on-consumer-chain) + +## External Data Structures + +[↑ Back to Outline](#outline) + +This section describes external data structures used by the CCV module. + +The CCV module uses the ABCI `ValidatorUpdate` data structure, which consists of a validator and its power (for more details, take a look at the [ABCI specification](https://github.com/tendermint/spec/blob/v0.7.1/spec/abci/abci.md#data-types)), i.e., + +```typescript +interface ValidatorUpdate { + pubKey: PublicKey + power: int64 +} +``` + +The provider chain sends to the consumer chain a list of `ValidatorUpdate`s, containing an entry for every validator that had its power updated. + +The data structures required for creating clients (i.e., `ClientState`, `ConsensusState`) are defined in [ICS 2](../../core/ics-002-client-semantics). +In the context of CCV, every chain is uniquely defined by their chain ID and the validator set. +Thus, CCV requires the `ClientState` to contain the chain ID and the `ConsensusState` for a particular height to contain the validator set at that height. +In addition, the `ClientState` should contain the `UnbondingPeriod`. +For an example, take a look at the `ClientState` and `ConsensusState` defined in [ICS 7](../../client/ics-007-tendermint-client). + +## CCV Data Structures + +[↑ Back to Outline](#outline) + +The CCV module is initialized through the `InitGenesis` method when the chain is first started. The initialization is done from a genesis state. This is the case for both provider and consumer chains: + +- On the provider chain, the genesis state is described by the following interface: + + ```typescript + interface ProviderGenesisState { + // a list of existing consumer chains + consumerStates: [ConsumerState] + } + ``` + + with `ConsumerState` defined as + + ```typescript + interface ConsumerState { + chainId: string + channelId: Identifier + } + ``` + +- On the consumer chain, the genesis state is described by the following interface: + + ```typescript + interface ConsumerGenesisState { + preCCV: Bool + unbondingPeriod: Duration + connId: Identifier + providerClientState: ClientState + providerConsensusState: ConsensusState + counterpartyClientId: Identifier + initialValSet: [ValidatorUpdate] + transferChannelId: Identifier + } + ``` + + - `preCCV` is a flag indicating whether the consumer CCV module starts in pre-CCV state. + In pre-CCV state the consumer CCV module MUST NOT pass validator updates to the underlying consensus engine. + If `preCCV == true`, then `connId` must be set. + - `unbondingPeriod` is the unbonding period on the consumer chain. + - `connId` is the ID of the connection end on the consumer chain on top of which the CCV channel will be established. + If `connId == ""`, a new client of the provider chain and a new connection on top of this client are created. + - `providerClientState` is the client state used to create a new client of the provider chain (as defined in [ICS 2](../../core/ics-002-client-semantics)). + If `connId != ""`, then `providerClientState` is ignored. + - `providerConsensusState` is the consensus state used to create a new client of the provider chain (as defined in [ICS 2](../../core/ics-002-client-semantics)). + If `connId != ""`, then `providerConsensusState` is ignored. + - `counterpartyClientId` is the ID of the client of the consumer chain on the provider chain. + Note that `counterpartyClientId` is only needed to allow the consumer CCV module to initiate the connection opening handshake. + If `connId != ""`, then `counterpartyClientId` is ignored. + - `initialValSet` is the first validator set that will start validating on this consumer chain. + - `transferChannelId` is the ID of a token transfer channel (as defined in [ICS 20](../../app/ics-020-fungible-token-transfer)) used for the Reward Distribution sub-protocol. + If `transferChannelId == ""`, a new token transfer channel is created on top of the same connection as the CCV channel. + +The provider CCV module handles governance proposals to add new consumer chains and to remove existing consumer chains. +While the structure of governance proposals is specific to every ABCI application (for an example, see the `Proposal` interface in the [Governance module documentation](/sdk/v0.53/build/modules/gov) of Cosmos SDK), +this specification expects the following fields to be part of the proposals to add new consumer chains (i.e., `ConsumerAdditionProposal`) and to remove existing ones (i.e., `ConsumerRemovalProposal`): + + ```typescript + interface ConsumerAdditionProposal { + chainId: string + spawnTime: Timestamp + connId: Identifier + unbondingPeriod: Duration + transferChannelId: Identifier + lockUnbondingOnTimeout: Bool + } + ``` + +- `chainId` is the proposed chain ID of the new consumer chain. It must be different from all other consumer chain IDs of the executing provider chain. +- `spawnTime` is the time on the provider chain at which the consumer chain genesis is finalized and all validators are responsible to start their consumer chain validator node. +- `connId` is the ID of the connection end on the provider chain on top of which the CCV channel will be established. + If `connId == ""`, a new client of the consumer chain and a new connection on top of this client are created. + Note that a sovereign chain can transition to a consumer chain while maintaining existing IBC channels to other chains by providing a valid `connId`. +- `unbondingPeriod` is the unbonding period on the consumer chain. +- `transferChannelId` is the ID of a token transfer channel (as defined in [ICS 20](../../app/ics-020-fungible-token-transfer)) used for the Reward Distribution sub-protocol. + If `transferChannelId == ""`, a new token transfer channel is created on top of the same connection as the CCV channel. + Note that `transferChannelId` is the ID of the channel end on the consumer chain. +- `lockUnbondingOnTimeout` is a boolean value that indicates whether the funds corresponding to the outstanding unbonding operations are to be released in case of a timeout. + If `lockUnbondingOnTimeout == true`, a governance proposal to stop the timed out consumer chain would be necessary to release the locked funds. + + ```typescript + interface ConsumerRemovalProposal { + chainId: string + stopTime: Timestamp + } + ``` + +- `chainId` is the chain ID of the consumer chain to be removed. It must be the ID of an existing consumer chain of the executing provider chain. +- `stopTime` is the time on the provider chain at which all validators are responsible to stop their consumer chain validator node. + +During the CCV channel opening handshake, the provider chain adds the address of its distribution module account to the channel version as metadata (as described in [ICS 4](../../core/ics-004-channel-and-packet-semantics/README#definitions)). +The metadata structure is described by the following interface: + +```typescript +interface CCVHandshakeMetadata { + providerDistributionAccount: string // the account's address + version: string +} +``` + +This specification assumes that the provider CCV module has access to the address of the distribution module account through the `GetDistributionAccountAddress()` method. For an example, take a look at the [auth module](/sdk/v0.53/build/modules/auth) of Cosmos SDK. + +## CCV Packets + +[↑ Back to Outline](#outline) + +The structure of the packets sent through the CCV channel is defined by the `Packet` interface in [ICS 4](../../core/ics-004-channel-and-packet-semantics). +The following packet data types are required by the CCV module: + +- `VSCPacketData` contains a list of validator updates, i.e., + + ```typescript + interface VSCPacketData { + // the id of this VSC + id: uint64 + // validator updates + updates: [ValidatorUpdate] + // downtime slash requests acknowledgements, + // i.e., list of validator addresses + downtimeSlashAcks: [string] + } + ``` + +- `VSCMaturedPacketData` contains the ID of the VSC that reached maturity, i.e., + + ```typescript + interface VSCMaturedPacketData { + id: uint64 // the id of the VSC that reached maturity + } + ``` + +- `SlashPacketData` contains a request to slash a validator, i.e., + + ```typescript + interface SlashPacketData { + valAddress: string // validator address, i.e., the hash of its public key + valPower: int64 + vscId: uint64 + downtime: Bool + } + ``` + +> Note that for brevity we use e.g., `VSCPacket` to refer to a packet with `VSCPacketData` as its data. + +Packets are acknowledged by the remote side by sending back an `Acknowledgement` that contains either a result (in case of success) or an error (as defined in [ICS 4](../../core/ics-004-channel-and-packet-semantics/README#acknowledgement-envelope)). +The following acknowledgement types are required by the CCV module: + +```typescript +type VSCPacketAcknowledgement = VSCPacketSuccess | VSCPacketError; +type VSCMaturedPacketAcknowledgement = VSCMaturedPacketSuccess | VSCMaturedPacketError; +type SlashPacketAcknowledgement = SlashPacketSuccess | SlashPacketError; +type PacketAcknowledgement = PacketSuccess | PacketError; // general ack +``` + +## CCV State + +[↑ Back to Outline](#outline) + +This section describes the internal state of the CCV module. For simplicity, the state is described by a set of variables; for each variable, both the type and a brief description is provided. In practice, all the state (except for hardcoded constants, e.g., `ProviderPortId`) is stored in a key/value store (KVS). The host state machine provides a KVS interface with three functions, i.e., `get()`, `set()`, and `delete()` (as defined in [ICS 24](../../core/ics-024-host-requirements)). + +- `ccvVersion = "ccv-1"` is the CCV expected version. Both the provider and the consumer chains need to agree on this version. +- `zeroTimeoutHeight = {0,0}` is the `timeoutHeight` (as defined in [ICS 4](../../core/ics-004-channel-and-packet-semantics)) used by CCV for sending packets. Note that CCV uses `ccvTimeoutTimestamp` for sending CCV packets and `transferTimeoutTimestamp` for transferring tokens. +- `ccvTimeoutTimestamp: uint64` is the `timeoutTimestamp` (as defined in [ICS 4](../../core/ics-004-channel-and-packet-semantics)) for sending CCV packets. The CCV protocol is responsible of setting `ccvTimeoutTimestamp` such that the *Correct Relayer* assumption is feasible. +- `transferTimeoutTimestamp: uint64` is the `timeoutTimestamp` (as defined in [ICS 4](../../core/ics-004-channel-and-packet-semantics)) for transferring tokens. + +### State on Provider Chain + +[↑ Back to Outline](#outline) + +- `ProviderPortId = "provider"` is the port ID the provider CCV module is expected to bind to. +- `initTimeout: uint64` is the maximum time duration the Channel Initialization subprotocol may execute, + i.e., for any consumer chain, if the CCV channel is not established within `initTimeout` since the consumer chain was registered, then the consumer chain is removed. +- `vscTimeout: uint64` is the maximum time duration between sending any `VSCPacket` to any consumer chain and receiving the corresponding `VSCMaturedPacket`, without timing out the consumer chain and consequently removing it. +- `pendingConsumerAdditionProposals: [ConsumerAdditionProposal]` is a list of pending governance proposals to add new consumer chains. +- `pendingConsumerRemovalProposals: [ConsumerRemovalProposal]` is a list of pending governance proposals to remove existing consumer chains. + Both lists of pending governance proposals expose the following interface: + +```typescript + interface [Proposal] { + // append a proposal to the list; the list is modified + Append(p: Proposal) + + // remove a proposal from the list; the list is modified + Remove(p: Proposal) + } + ``` + +- `lockUnbondingOnTimeout: Map` is a mapping from consumer chain IDs to the boolean values indicating whether the funds corresponding to the in progress unbonding operations are to be released in case of a timeout. +- `chainToClient: Map` is a mapping from consumer chain IDs to the associated client IDs. +- `chainToConnection: Map` is a mapping from consumer chain IDs to the associated connection IDs. +- `chainToChannel: Map` is a mapping from consumer chain IDs to the CCV channel IDs. +- `channelToChain: Map` is a mapping from CCV channel IDs to consumer chain IDs. +- `initTimeoutTimestamps: Map` is a mapping from consumer chain IDs to init timeout timestamps, see `initTimeout`. +- `pendingVSCPackets: Map` is a mapping from consumer chain IDs to a list of pending `VSCPacketData`s that must be sent to the consumer chain once the CCV channel is established. The map exposes the following interface: + + ```typescript + interface Map { + // append a VSCPacketData to the list mapped to chainId; + // the list is modified + Append(chainId: string, data: VSCPacketData) + + // remove all the VSCPacketData mapped to chainId; + // the list is modified + Remove(chainId: string) + } +- `vscId: uint64` is a monotonic strictly increasing and positive ID that is used to uniquely identify the VSCs sent to the consumer chains. + Note that `0` is used as a special ID for the mapping from consumer heights to provider heights. +- `vscSendTimestamps: Map<(string, uint64), uint64>` is a mapping from `(chainId, vscId)` tuples to the timestamps of sending `VSCPacket`s. +- `initialHeights: Map` is a mapping from consumer chain IDs to the heights on the provider chain. + For every consumer chain, the mapping stores the height when the CCV channel to that consumer chain is established. + Note that the provider validator set at this height matches the validator set at the height when the first VSC is provided to that consumer chain. + It enables the mapping from consumer heights to provider heights. +- `VSCtoH: Map` is a mapping from VSC IDs to heights on the provider chain. It enables the mapping from consumer heights to provider heights, + i.e., the voting power at height `VSCtoH[id]` on the provider chain was last updated by the validator updates contained in the VSC with ID `id`. +- `unbondingOps: Map` is a mapping that enables accessing for every unbonding operation the list of consumer chains that are still unbonding. When unbonding operations are initiated, the Staking module calls the `AfterUnbondingInitiated()` [hook](./methods#ccv-pcf-hook-afubopcr1)); this leads to the creation of a new `UnbondingOperation`, which is defined as + + ```typescript + interface UnbondingOperation { + id: uint64 + // list of consumer chain IDs that are still unbonding + unbondingChainIds: [string] + } + ``` + +- `vscToUnbondingOps: Map<(string, uint64), [uint64]>` is a mapping from `(chainId, vscId)` tuples to a list of unbonding operation IDs. + It enables the provider CCV module to match a `VSCMaturedPacket{vscId}`, received from a consumer chain with `chainId`, with the corresponding unbonding operations. + As a result, `chainId` can be removed from the list of consumer chains that are still unbonding these operations. + For more details see how received `VSCMaturedPacket`s [are handled](./methods#ccv-pcf-rcvmat1). +- `maturedUnbondingOps: [uint64]` is a list of IDs of matured unbonding operations (from the perspective of the consumer chains), for which notifications can be sent to the Staking module (see `stakingKeeper.UnbondingCanComplete`). + Note that `maturedUnbondingOps` is emptied at the end of each block. +- `downtimeSlashRequests: Map` is a mapping from `chainId`s to lists of validator addresses, + i.e., `downtimeSlashRequests[chainId]` contains all the validator addresses for which the provider chain received slash requests for downtime from the consumer chain with `chainId`. + +### State on Consumer Chain + +[↑ Back to Outline](#outline) + +- `ConsumerPortId = "consumer"` is the port ID the consumer CCV module is expected to bind to. +- `ConsumerUnbondingPeriod: Duration` is the unbonding period on the consumer chain. +- `preCCV: Bool` is a flag indicating whether the consumer CCV module starts in pre-CCV state. + In pre-CCV state, the consumer CCV module MUST NOT pass validator updates to the underlying consensus engine. +- `providerClientId: Identifier` identifies the client of the provider chain (on the consumer chain) that the CCV channel is build upon. +- `providerChannel: Identifier` identifies the consumer's channel end of the CCV channel. +- `ccvValidatorSet: ` is a mapping that stores the validators in the validator set of the consumer chain. +- `receivedVSCs: [VSCPacketData]` is a list of data items (i.e., `VSCPacketData`) received in `VSCPacket`s that are not yet applied. +- `HtoVSC: Map` is a mapping from consumer chain heights to VSC IDs. It enables the mapping from consumer heights to provider heights., i.e., + - if `HtoVSC[h] == 0`, then the voting power on the consumer chain at height `h` was setup at genesis during Channel Initialization; + - otherwise, the voting power on the consumer chain at height `h` was updated by the VSC with ID `HtoVSC[h]`. +- `maturingVSCs: [(uint64, uint64)]` is a list of `(id, ts)` tuples, where `id` is the ID of a VSC received via a `VSCPacket` and `ts` is the timestamp at which the VSC reaches maturity on the consumer chain. + The list is used to keep track of when unbonding operations are matured on the consumer chain. It exposes the following interface: + + ```typescript + interface [(uint64, uint64)] { + // add a VSC id with its maturity timestamp to the list; + // the list is modified + Add(id: uint64, ts: uint64) + + // return the list sorted by the maturity timestamps; + // the original list is not modified + SortedByMaturityTime(): [(uint64, uint64)] + + // remove (id, ts) from the list; + // the list is modified + Remove(id: uint64, ts: uint64) + } + ``` + +- `pendingSlashRequests: [SlashRequest]` is a list of pending `SlashRequest`s that must be sent to the provider chain once the CCV channel is established. A `SlashRequest` consist of a `SlashPacketData` and a flag indicating whether the request is for downtime slashing. The list exposes the following interface: + + ```typescript + interface SlashRequest { + data: SlashPacketData + downtime: Bool + } + interface [SlashRequest] { + // append a SlashRequest to the list; + // the list is modified + Append(data: SlashRequest) + + // return the reverse list, i.e., latest SlashRequest first; + // the original list is not modified + Reverse(): [SlashRequest] + + // remove all the SlashRequest; + // the list is modified + RemoveAll() + } + ``` + +- `outstandingDowntime: ` is a mapping from validator addresses to boolean values. + `outstandingDowntime[valAddr] == TRUE` entails that the consumer chain sent a request to slash for downtime the validator with address `valAddr`. + `outstandingDowntime[valAddr]` is set to false once the consumer chain receives a confirmation that the downtime slash request was received by the provider chain, i.e., a `VSCPacket` that contains `valAddr` in `downtimeSlashAcks`. + The mapping enables the consumer CCV module to avoid sending to the provider chain multiple slashing requests for the same downtime infraction. +- `providerDistributionAccount: string` is the address of the distribution module account on the provider chain. It enables the consumer chain to transfer rewards to the provider chain. +- `distributionChannelId: Identifier` is the ID of the distribution token transfer channel used for sending rewards to the provider chain. +- `BlocksPerDistributionTransfer: int64` is the interval (in number of blocks) between two distribution token transfers. +- `lastDistributionTransferHeight: Height` is the block height of the last distribution token transfer. +- `ccvAccount: string` is the address of the CCV module account where a fraction of the consumer chain rewards are collected before being transferred to the provider chain. diff --git a/ibc/next/spec/app/ics-028-cross-chain-validation/figures/ccv-distribution-overview.excalidraw b/ibc/next/spec/app/ics-028-cross-chain-validation/figures/ccv-distribution-overview.excalidraw new file mode 100644 index 00000000..9a4cf851 --- /dev/null +++ b/ibc/next/spec/app/ics-028-cross-chain-validation/figures/ccv-distribution-overview.excalidraw @@ -0,0 +1,1448 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "type": "text", + "version": 1005, + "versionNonce": 942012557, + "isDeleted": false, + "id": "DcYomqVwJx0rUjMvf5S5b", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1391.0634920634916, + "y": 1852.9047619047617, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 361, + "height": 35, + "seed": 484186313, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1648717847398, + "link": null, + "fontSize": 28, + "fontFamily": 1, + "text": "CCV - Reward Distribution", + "baseline": 25, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "CCV - Reward Distribution" + }, + { + "type": "text", + "version": 1473, + "versionNonce": 1279271715, + "isDeleted": false, + "id": "yqi6dzvpzblq17ysowkTo", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1184.1995040738243, + "y": 1919.7150027318748, + "strokeColor": "#364fc7", + "backgroundColor": "transparent", + "width": 138, + "height": 26, + "seed": 578772677, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1648717830267, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Provider Chain", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Provider Chain" + }, + { + "type": "text", + "version": 1700, + "versionNonce": 380537603, + "isDeleted": false, + "id": "Y19fC1uuzabCFyV0s97Ip", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1774.6009368748905, + "y": 1919.7150027318748, + "strokeColor": "#e67700", + "backgroundColor": "transparent", + "width": 148, + "height": 26, + "seed": 1161289003, + "groupIds": [], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1648717824957, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Consumer Chain", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Consumer Chain" + }, + { + "type": "text", + "version": 1418, + "versionNonce": 856000099, + "isDeleted": false, + "id": "A_uPQosGByCb18jg5F8J3", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1608.6178858721328, + "y": 1957.1879109167996, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 112, + "height": 26, + "seed": 1240462166, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1648717754192, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "CCV Module", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "CCV Module" + }, + { + "type": "arrow", + "version": 3989, + "versionNonce": 2125688557, + "isDeleted": false, + "id": "vpFHq3t2ppDoZ0A65BDZu", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1551.1900175267103, + "y": 2344.842556707134, + "strokeColor": "#000000", + "backgroundColor": "#ced4da", + "width": 128.79181255561082, + "height": 0.08876270859309443, + "seed": 564068565, + "groupIds": [ + "kCy-i3wrt_ZLgIeQ4otUP" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1648718352186, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -128.79181255561082, + -0.08876270859309443 + ] + ] + }, + { + "type": "text", + "version": 2037, + "versionNonce": 196149859, + "isDeleted": false, + "id": "REPxg78R4E5rz3sm5KHSv", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1409.5528637544644, + "y": 2302.708121633686, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 146, + "height": 25, + "seed": 208528123, + "groupIds": [ + "kCy-i3wrt_ZLgIeQ4otUP" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1648718352186, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "TokenTransfer", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "TokenTransfer" + }, + { + "id": "IjbvMm7oV9sVgP7WlGh5E", + "type": "line", + "x": 1799.9264992474484, + "y": 2096.174492510282, + "width": 0.4985622223937298, + "height": 33.65304102189839, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "groupIds": [], + "strokeSharpness": "round", + "seed": 806893027, + "version": 108, + "versionNonce": 348679437, + "isDeleted": false, + "boundElements": null, + "updated": 1648718383497, + "link": null, + "points": [ + [ + 0, + 0 + ], + [ + 0.4985622223937298, + 33.65304102189839 + ] + ], + "lastCommittedPoint": null, + "startBinding": null, + "endBinding": null, + "startArrowhead": null, + "endArrowhead": null + }, + { + "type": "rectangle", + "version": 3280, + "versionNonce": 1529278413, + "isDeleted": false, + "id": "34mJiRUfZv_whlGRmiJJO", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 20, + "angle": 0, + "x": 1580.7964573007043, + "y": 1993.826747397683, + "strokeColor": "#e67700", + "backgroundColor": "#e67700", + "width": 438, + "height": 90.41269841269803, + "seed": 906912827, + "groupIds": [ + "dM4n286bGb7i0G9C3JQhZ" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "DURyamuWvIhE5o-GLqnvp", + "type": "arrow" + }, + { + "id": "-sQ1lqt81ejZKXt6Q2HFf", + "type": "arrow" + }, + { + "id": "gMMtc7H_hFXaSquI_JbUz", + "type": "arrow" + }, + { + "id": "qUiA0J-sfT84YpVQWlEot", + "type": "arrow" + }, + { + "id": "jxiIfnYuV__VAbb-JgmY7", + "type": "arrow" + }, + { + "id": "cFz81tlJ2NMZiYzWVMuf6", + "type": "arrow" + }, + { + "id": "vpFHq3t2ppDoZ0A65BDZu", + "type": "arrow" + } + ], + "updated": 1648718365618, + "link": null + }, + { + "type": "text", + "version": 1668, + "versionNonce": 47873923, + "isDeleted": false, + "id": "m_vQSEBRga8RR7VuL27UY", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1821.73693349118, + "y": 1999.4973823183186, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 109, + "height": 50, + "seed": 765969819, + "groupIds": [ + "lNYd5uxp6Xm5xLMU-zrby", + "dM4n286bGb7i0G9C3JQhZ" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "tvGd783eUc39eNWP1L7-j", + "type": "arrow" + } + ], + "updated": 1648718365618, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "fraction of\nrewards", + "baseline": 43, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "fraction of\nrewards" + }, + { + "type": "arrow", + "version": 3963, + "versionNonce": 229731885, + "isDeleted": false, + "id": "tvGd783eUc39eNWP1L7-j", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1932.8019559784343, + "y": 2060.997674669792, + "strokeColor": "#000000", + "backgroundColor": "#ced4da", + "width": 125.15697875770252, + "height": 1.0514920517930477, + "seed": 321384565, + "groupIds": [ + "Uvbj_Wiv_4OirTlk_pHjj", + "lNYd5uxp6Xm5xLMU-zrby", + "dM4n286bGb7i0G9C3JQhZ" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1648718365618, + "link": null, + "startBinding": { + "elementId": "m_vQSEBRga8RR7VuL27UY", + "focus": -1.415085392769348, + "gap": 11.50029235147349 + }, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -125.15697875770252, + -1.0514920517930477 + ] + ] + }, + { + "id": "xbQJbKMN6ij9ve7OviLr7", + "type": "rectangle", + "x": 1599.902692012232, + "y": 2035.4081490120375, + "width": 188, + "height": 35, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "dM4n286bGb7i0G9C3JQhZ" + ], + "strokeSharpness": "sharp", + "seed": 210145315, + "version": 332, + "versionNonce": 1528635533, + "isDeleted": false, + "boundElements": [ + { + "type": "text", + "id": "CYcPnlANLHU04SN9990JF" + } + ], + "updated": 1648718365618, + "link": null + }, + { + "id": "CYcPnlANLHU04SN9990JF", + "type": "text", + "x": 1604.902692012232, + "y": 2041.4081490120375, + "width": 178, + "height": 23, + "angle": 0, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "groupIds": [ + "dM4n286bGb7i0G9C3JQhZ" + ], + "strokeSharpness": "sharp", + "seed": 15459693, + "version": 299, + "versionNonce": 1227668163, + "isDeleted": false, + "boundElements": null, + "updated": 1648718365618, + "link": null, + "text": "$ CCV account", + "fontSize": 20, + "fontFamily": 1, + "textAlign": "center", + "verticalAlign": "middle", + "baseline": 17, + "containerId": "xbQJbKMN6ij9ve7OviLr7", + "originalText": "$ CCV account" + }, + { + "type": "text", + "version": 1938, + "versionNonce": 958629613, + "isDeleted": false, + "id": "Oz5lUjmcWXSCVOUr-aDA6", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1960.8164836480091, + "y": 1999.0985727945085, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 51, + "height": 50, + "seed": 756640341, + "groupIds": [ + "dM4n286bGb7i0G9C3JQhZ" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1648718365618, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Block\nHc", + "baseline": 43, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Block\nHc" + }, + { + "type": "rectangle", + "version": 3445, + "versionNonce": 32402019, + "isDeleted": false, + "id": "smdUW8hJpPhBv4aV5ay_q", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 20, + "angle": 0, + "x": 1580.7964573007043, + "y": 2266.901858466779, + "strokeColor": "#e67700", + "backgroundColor": "#e67700", + "width": 438, + "height": 90.41269841269803, + "seed": 1103023629, + "groupIds": [ + "pZnJ-ggCgfXjtpihWQO_h" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "DURyamuWvIhE5o-GLqnvp", + "type": "arrow" + }, + { + "id": "-sQ1lqt81ejZKXt6Q2HFf", + "type": "arrow" + }, + { + "id": "gMMtc7H_hFXaSquI_JbUz", + "type": "arrow" + }, + { + "id": "qUiA0J-sfT84YpVQWlEot", + "type": "arrow" + }, + { + "id": "jxiIfnYuV__VAbb-JgmY7", + "type": "arrow" + }, + { + "id": "cFz81tlJ2NMZiYzWVMuf6", + "type": "arrow" + }, + { + "id": "vpFHq3t2ppDoZ0A65BDZu", + "type": "arrow" + } + ], + "updated": 1648718365618, + "link": null + }, + { + "type": "text", + "version": 1833, + "versionNonce": 709763405, + "isDeleted": false, + "id": "F6tHqrlehaqv4NgVfyYod", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1821.73693349118, + "y": 2272.5724933874144, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 109, + "height": 50, + "seed": 1491510595, + "groupIds": [ + "iVaTc7j72nXI1Q2rCU61q", + "pZnJ-ggCgfXjtpihWQO_h" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "J8lhUtkiur7yuJP0IVsWe", + "type": "arrow" + } + ], + "updated": 1648718365618, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "fraction of\nrewards", + "baseline": 43, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "fraction of\nrewards" + }, + { + "type": "arrow", + "version": 4359, + "versionNonce": 35202563, + "isDeleted": false, + "id": "J8lhUtkiur7yuJP0IVsWe", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1932.8019559784343, + "y": 2334.072785738888, + "strokeColor": "#000000", + "backgroundColor": "#ced4da", + "width": 125.15697875770252, + "height": 1.0514920517930477, + "seed": 171148397, + "groupIds": [ + "pplowjM61J9zLv8WW_Iet", + "iVaTc7j72nXI1Q2rCU61q", + "pZnJ-ggCgfXjtpihWQO_h" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1648718365618, + "link": null, + "startBinding": { + "elementId": "F6tHqrlehaqv4NgVfyYod", + "focus": -1.415085392769348, + "gap": 11.50029235147349 + }, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -125.15697875770252, + -1.0514920517930477 + ] + ] + }, + { + "type": "rectangle", + "version": 494, + "versionNonce": 279670179, + "isDeleted": false, + "id": "Alaps4d4CIl7xNCwR5rzQ", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1599.902692012232, + "y": 2308.4832600811333, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 188, + "height": 35, + "seed": 134677731, + "groupIds": [ + "pZnJ-ggCgfXjtpihWQO_h" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "ew0ofctlhOyFp3fOfssPc", + "type": "text" + }, + { + "type": "text", + "id": "ew0ofctlhOyFp3fOfssPc" + } + ], + "updated": 1648718365619, + "link": null + }, + { + "type": "text", + "version": 464, + "versionNonce": 876999181, + "isDeleted": false, + "id": "ew0ofctlhOyFp3fOfssPc", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1604.902692012232, + "y": 2314.4832600811333, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 178, + "height": 23, + "seed": 595750605, + "groupIds": [ + "pZnJ-ggCgfXjtpihWQO_h" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1648718365619, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "$ CCV account", + "baseline": 17, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "Alaps4d4CIl7xNCwR5rzQ", + "originalText": "$ CCV account" + }, + { + "type": "text", + "version": 2105, + "versionNonce": 282313027, + "isDeleted": false, + "id": "qKtTARj56MbaSPbxOCPJk", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1959.8164836480091, + "y": 2272.1736838636043, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 51, + "height": 50, + "seed": 523923587, + "groupIds": [ + "pZnJ-ggCgfXjtpihWQO_h" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1648718365619, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Block\nHc+x", + "baseline": 43, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Block\nHc+x" + }, + { + "type": "rectangle", + "version": 576, + "versionNonce": 598161635, + "isDeleted": false, + "id": "GLbhbcWSEyuebylqDnpU2", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1187.9667306872643, + "y": 2288.408149012037, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 188, + "height": 57, + "seed": 1340530701, + "groupIds": [ + "VtmzX2Iudw6NpYzBxjnOR", + "0Xag4f3CHNBceQxWD5THH" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "v7H0D2SFSeTqd98kFr9Tn", + "type": "text" + }, + { + "id": "v7H0D2SFSeTqd98kFr9Tn", + "type": "text" + }, + { + "type": "text", + "id": "v7H0D2SFSeTqd98kFr9Tn" + } + ], + "updated": 1648718352186, + "link": null + }, + { + "type": "text", + "version": 550, + "versionNonce": 942635725, + "isDeleted": false, + "id": "v7H0D2SFSeTqd98kFr9Tn", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1192.9667306872643, + "y": 2293.408149012037, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 178, + "height": 46, + "seed": 780186435, + "groupIds": [ + "VtmzX2Iudw6NpYzBxjnOR", + "0Xag4f3CHNBceQxWD5THH" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1648718352186, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "$ distribution \naccount", + "baseline": 40, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "GLbhbcWSEyuebylqDnpU2", + "originalText": "$ distribution account" + }, + { + "type": "rectangle", + "version": 3481, + "versionNonce": 1085547651, + "isDeleted": false, + "id": "AkC-Q6AHwm6Ua2co050XG", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 20, + "angle": 0, + "x": 1105.9667306872643, + "y": 2267.868466472355, + "strokeColor": "#1864ab", + "backgroundColor": "#1864ab", + "width": 288.25, + "height": 88.57936507936469, + "seed": 1841008003, + "groupIds": [ + "0Xag4f3CHNBceQxWD5THH" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "DURyamuWvIhE5o-GLqnvp", + "type": "arrow" + }, + { + "id": "-sQ1lqt81ejZKXt6Q2HFf", + "type": "arrow" + }, + { + "id": "gMMtc7H_hFXaSquI_JbUz", + "type": "arrow" + }, + { + "id": "qUiA0J-sfT84YpVQWlEot", + "type": "arrow" + }, + { + "id": "jxiIfnYuV__VAbb-JgmY7", + "type": "arrow" + }, + { + "id": "cFz81tlJ2NMZiYzWVMuf6", + "type": "arrow" + } + ], + "updated": 1648718352186, + "link": null + }, + { + "type": "text", + "version": 1836, + "versionNonce": 1869650221, + "isDeleted": false, + "id": "ukJYsO2TyJCEXc5fyeEt_", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1111.4667306872643, + "y": 2275.908149012037, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 51, + "height": 50, + "seed": 1647435235, + "groupIds": [ + "0Xag4f3CHNBceQxWD5THH" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1648718352186, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Block\nHp2", + "baseline": 43, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Block\nHp2" + }, + { + "type": "arrow", + "version": 3920, + "versionNonce": 563157581, + "isDeleted": false, + "id": "t6EBWr_9oI5RhHG2G77KC", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1557.4055642998305, + "y": 2074.3425567071336, + "strokeColor": "#000000", + "backgroundColor": "#ced4da", + "width": 128.79181255561082, + "height": 0.08876270859309443, + "seed": 1421736451, + "groupIds": [ + "jL3JwgrGJGsJ9iKIcLo8U" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1648717806780, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -128.79181255561082, + -0.08876270859309443 + ] + ] + }, + { + "type": "text", + "version": 1968, + "versionNonce": 1331576067, + "isDeleted": false, + "id": "Q1QsNgKGpkQte_Ty3Gq5x", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1415.7684105275844, + "y": 2032.2081216336865, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 146, + "height": 25, + "seed": 1505287085, + "groupIds": [ + "jL3JwgrGJGsJ9iKIcLo8U" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1648717806780, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "TokenTransfer", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "TokenTransfer" + }, + { + "type": "rectangle", + "version": 509, + "versionNonce": 932698541, + "isDeleted": false, + "id": "s_dUdYMbfAgY-wx64-cZy", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1187.9667306872643, + "y": 2017.908149012037, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 188, + "height": 57, + "seed": 1603649955, + "groupIds": [ + "XrGNgTVaQYbbqnVbqe1WW", + "X2TBHJO-i4ICHszzaNf9v" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "HgpbjFpWkkElb6JHK30jf", + "type": "text" + }, + { + "id": "HgpbjFpWkkElb6JHK30jf", + "type": "text" + }, + { + "id": "HgpbjFpWkkElb6JHK30jf", + "type": "text" + }, + { + "type": "text", + "id": "HgpbjFpWkkElb6JHK30jf" + } + ], + "updated": 1648717890359, + "link": null + }, + { + "type": "text", + "version": 482, + "versionNonce": 296592291, + "isDeleted": false, + "id": "HgpbjFpWkkElb6JHK30jf", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1192.9667306872643, + "y": 2022.908149012037, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 178, + "height": 46, + "seed": 1591401997, + "groupIds": [ + "XrGNgTVaQYbbqnVbqe1WW", + "X2TBHJO-i4ICHszzaNf9v" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1648717890359, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "$ distribution \naccount", + "baseline": 40, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "s_dUdYMbfAgY-wx64-cZy", + "originalText": "$ distribution account" + }, + { + "type": "rectangle", + "version": 3413, + "versionNonce": 1680481293, + "isDeleted": false, + "id": "nAD6yE-Il7_lA6MHEDRRU", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 20, + "angle": 0, + "x": 1105.9667306872643, + "y": 1997.368466472355, + "strokeColor": "#1864ab", + "backgroundColor": "#1864ab", + "width": 288.25, + "height": 88.57936507936469, + "seed": 928224579, + "groupIds": [ + "X2TBHJO-i4ICHszzaNf9v" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "DURyamuWvIhE5o-GLqnvp", + "type": "arrow" + }, + { + "id": "-sQ1lqt81ejZKXt6Q2HFf", + "type": "arrow" + }, + { + "id": "gMMtc7H_hFXaSquI_JbUz", + "type": "arrow" + }, + { + "id": "qUiA0J-sfT84YpVQWlEot", + "type": "arrow" + }, + { + "id": "jxiIfnYuV__VAbb-JgmY7", + "type": "arrow" + }, + { + "id": "cFz81tlJ2NMZiYzWVMuf6", + "type": "arrow" + } + ], + "updated": 1648717890359, + "link": null + }, + { + "type": "text", + "version": 1765, + "versionNonce": 1612658499, + "isDeleted": false, + "id": "24NFD0EAJBhRkLJaPjCB7", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1111.4667306872643, + "y": 2005.408149012037, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 51, + "height": 50, + "seed": 1229821037, + "groupIds": [ + "X2TBHJO-i4ICHszzaNf9v" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1648717890359, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "Block\nHp1", + "baseline": 43, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "Block\nHp1" + }, + { + "type": "rectangle", + "version": 3523, + "versionNonce": 1093005251, + "isDeleted": false, + "id": "5UhO9vf3ic8tfV-ct-H4a", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 20, + "angle": 0, + "x": 1580.7964573007043, + "y": 2141.4520030011813, + "strokeColor": "#e67700", + "backgroundColor": "#e67700", + "width": 438, + "height": 67.91269841269799, + "seed": 1223050061, + "groupIds": [ + "kEhD5pp9ZyDcmuVHj7jXo" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "Mi1I3PpLY1MQGIPxt7fC1", + "type": "arrow" + }, + { + "id": "DURyamuWvIhE5o-GLqnvp", + "type": "arrow" + }, + { + "id": "-sQ1lqt81ejZKXt6Q2HFf", + "type": "arrow" + }, + { + "id": "gMMtc7H_hFXaSquI_JbUz", + "type": "arrow" + }, + { + "id": "qUiA0J-sfT84YpVQWlEot", + "type": "arrow" + }, + { + "id": "jxiIfnYuV__VAbb-JgmY7", + "type": "arrow" + }, + { + "id": "cFz81tlJ2NMZiYzWVMuf6", + "type": "arrow" + }, + { + "id": "vpFHq3t2ppDoZ0A65BDZu", + "type": "arrow" + } + ], + "updated": 1648718382746, + "link": null + }, + { + "type": "text", + "version": 1929, + "versionNonce": 1078206957, + "isDeleted": false, + "id": "ORXBeHtSMUVrEyiFaIik_", + "fillStyle": "hachure", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1804.48693349118, + "y": 2149.6226379218165, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 196, + "height": 25, + "seed": 1376527363, + "groupIds": [ + "EZZbZ1FR2RI1InChFO1wi", + "kEhD5pp9ZyDcmuVHj7jXo" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "0hQr8j4kqSD8M3pL0Qbq9", + "type": "arrow" + } + ], + "updated": 1648718382746, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "fraction of rewards", + "baseline": 18, + "textAlign": "center", + "verticalAlign": "top", + "containerId": null, + "originalText": "fraction of rewards" + }, + { + "type": "arrow", + "version": 4612, + "versionNonce": 1861812067, + "isDeleted": false, + "id": "0hQr8j4kqSD8M3pL0Qbq9", + "fillStyle": "hachure", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1985.0603540692218, + "y": 2190.3258903405326, + "strokeColor": "#000000", + "backgroundColor": "#ced4da", + "width": 177.41537684849004, + "height": 0.2544521190352498, + "seed": 1060786605, + "groupIds": [ + "fPmYjanoLwZxiv--xyo7a", + "EZZbZ1FR2RI1InChFO1wi", + "kEhD5pp9ZyDcmuVHj7jXo" + ], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1648718382746, + "link": null, + "startBinding": { + "elementId": "ORXBeHtSMUVrEyiFaIik_", + "focus": -2.221803403364259, + "gap": 15.703252418716147 + }, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "triangle", + "points": [ + [ + 0, + 0 + ], + [ + -177.41537684849004, + -0.2544521190352498 + ] + ] + }, + { + "type": "rectangle", + "version": 563, + "versionNonce": 2064194307, + "isDeleted": false, + "id": "AaZnP-uk9pLjwUgVCuPxX", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1599.902692012232, + "y": 2160.5334046155363, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 188, + "height": 35, + "seed": 630107043, + "groupIds": [ + "kEhD5pp9ZyDcmuVHj7jXo" + ], + "strokeSharpness": "sharp", + "boundElements": [ + { + "id": "y72sz2bjJqP1nhMBGOJmw", + "type": "text" + }, + { + "id": "y72sz2bjJqP1nhMBGOJmw", + "type": "text" + }, + { + "type": "text", + "id": "y72sz2bjJqP1nhMBGOJmw" + } + ], + "updated": 1648718382747, + "link": null + }, + { + "type": "text", + "version": 532, + "versionNonce": 1777093293, + "isDeleted": false, + "id": "y72sz2bjJqP1nhMBGOJmw", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1604.902692012232, + "y": 2166.5334046155363, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 178, + "height": 23, + "seed": 1086166029, + "groupIds": [ + "kEhD5pp9ZyDcmuVHj7jXo" + ], + "strokeSharpness": "sharp", + "boundElements": [], + "updated": 1648718382747, + "link": null, + "fontSize": 20, + "fontFamily": 1, + "text": "$ CCV account", + "baseline": 17, + "textAlign": "center", + "verticalAlign": "middle", + "containerId": "AaZnP-uk9pLjwUgVCuPxX", + "originalText": "$ CCV account" + }, + { + "type": "line", + "version": 162, + "versionNonce": 1275754051, + "isDeleted": false, + "id": "LWfeCA_MHMz7HlX7Nl_HY", + "fillStyle": "solid", + "strokeWidth": 4, + "strokeStyle": "dotted", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1799.471492174934, + "y": 2221.3874474682207, + "strokeColor": "#000000", + "backgroundColor": "transparent", + "width": 0.4985622223937298, + "height": 33.65304102189839, + "seed": 809602285, + "groupIds": [], + "strokeSharpness": "round", + "boundElements": [], + "updated": 1648718383497, + "link": null, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": null, + "points": [ + [ + 0, + 0 + ], + [ + 0.4985622223937298, + 33.65304102189839 + ] + ] + } + ], + "appState": { + "gridSize": null, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} \ No newline at end of file diff --git a/ibc/next/spec/app/ics-028-cross-chain-validation/figures/ccv-distribution-overview.png b/ibc/next/spec/app/ics-028-cross-chain-validation/figures/ccv-distribution-overview.png new file mode 100644 index 0000000000000000000000000000000000000000..40f740d5b1e4562931bf5902c89db3bc197228ad GIT binary patch literal 314861 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

LWsO_B!X<2hY5dR333W$s({ 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

-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

rHG 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 MYQ$n@8vYRYzp#yS%K!iX literal 0 HcmV?d00001 diff --git a/ibc/next/spec/app/ics-020-fungible-token-transfer/deprecated/forwarding-3-chains.excalidraw b/ibc/next/spec/app/ics-020-fungible-token-transfer/deprecated/forwarding-3-chains.excalidraw new file mode 100644 index 00000000..01c74839 --- /dev/null +++ b/ibc/next/spec/app/ics-020-fungible-token-transfer/deprecated/forwarding-3-chains.excalidraw @@ -0,0 +1,2425 @@ +{ + "type": "excalidraw", + "version": 2, + "source": "https://excalidraw.com", + "elements": [ + { + "type": "arrow", + "version": 500, + "versionNonce": 547005722, + "index": "a6", + "isDeleted": false, + "id": "kGNyejkGXJAPWBL3iSem9", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 575.5231779834404, + "y": 174.3624805827368, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 2.9839978389845783, + "height": 1138.761319881039, + "seed": 793816151, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1721391257529, + "link": null, + "locked": false, + "startBinding": { + "elementId": "byOxN_Be5RoqJHMRG-hDg", + "focus": 0.10736976985156056, + "gap": 12.149791114464506 + }, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 2.9839978389845783, + 1138.761319881039 + ] + ] + }, + { + "type": "text", + "version": 1150, + "versionNonce": 836846598, + "index": "a7", + "isDeleted": false, + "id": "UiYbIvXxMv8Dp5bJa3fUB", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 928.1594076363192, + "y": 409.82489659174723, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 718.7401123046875, + "height": 450, + "seed": 1216763255, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721398151027, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "if received tokens trace is prefixed by \"transfer/channelAToB\" {\n transfer tokens from escrow[channelBtoA] to forwarding[channelBtoA]\n} else {\n mint IBC vouchers to forwarding[channelBtoA]\n}\n\nsend packetBtoC{\n sender: forwarding[channelBtoA]\n receiver: chainC...\n}\n\nif sent tokens trace is prefixed by \"transfer/channelBToC\" {\n burn vouchers from forwarding[channelBtoA]\n} else {\n transfer tokens from forwarding[channelBtoA] to escrow[channelBtoC]\n}\n\nstore packetAtoB", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "if received tokens trace is prefixed by \"transfer/channelAToB\" {\n transfer tokens from escrow[channelBtoA] to forwarding[channelBtoA]\n} else {\n mint IBC vouchers to forwarding[channelBtoA]\n}\n\nsend packetBtoC{\n sender: forwarding[channelBtoA]\n receiver: chainC...\n}\n\nif sent tokens trace is prefixed by \"transfer/channelBToC\" {\n burn vouchers from forwarding[channelBtoA]\n} else {\n transfer tokens from forwarding[channelBtoA] to escrow[channelBtoC]\n}\n\nstore packetAtoB", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "text", + "version": 199, + "versionNonce": 522645466, + "index": "a9", + "isDeleted": false, + "id": "byOxN_Be5RoqJHMRG-hDg", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 544.1754309597408, + "y": 137.2126894682723, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 70.09996032714844, + "height": 25, + "seed": 1685913625, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [ + { + "id": "kGNyejkGXJAPWBL3iSem9", + "type": "arrow" + } + ], + "updated": 1721390761541, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "chain A", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "chain A", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "text", + "version": 318, + "versionNonce": 2134088154, + "index": "aA", + "isDeleted": false, + "id": "VTjpRVLCJCTyb1Jvl_5HW", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 286.5043327213947, + "y": 217.14507867516056, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 263.75982666015625, + "height": 175, + "seed": 1363487673, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721390783916, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "send packetAtoB {\n sender: chainA...\n receiver: chainC...\n forwardingPath: {\n \"transfer/channelBtoC\"\n }\n}", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "send packetAtoB {\n sender: chainA...\n receiver: chainC...\n forwardingPath: {\n \"transfer/channelBtoC\"\n }\n}", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "text", + "version": 850, + "versionNonce": 325918042, + "index": "aC", + "isDeleted": false, + "id": "7yeRy5aZS6ORAypCf5nLj", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1992.292466706081, + "y": 879.3893557920742, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 420.399658203125, + "height": 175, + "seed": 742789945, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721398431148, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "if source {\n transfer tokens from escrow to chainC...\n} else {\n mint IBC vouchers to chainC...\n}\n\nwrite ack (packetBtoC)", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "if source {\n transfer tokens from escrow to chainC...\n} else {\n mint IBC vouchers to chainC...\n}\n\nwrite ack (packetBtoC)", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 218, + "versionNonce": 739724954, + "index": "aD", + "isDeleted": false, + "id": "-LqXV4Ju2E1Ik3GMk8X0k", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 272.18387866690665, + "y": 205.41736555811792, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 288.0428630503233, + "height": 197.54554923377296, + "seed": 1281030455, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "8HGAHjo9alsyXDCxeEhAp", + "type": "arrow" + } + ], + "updated": 1721390783920, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 163, + "versionNonce": 749919450, + "index": "aE", + "isDeleted": false, + "id": "Vz7AOU9wIKtBTUtD_1KPd", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 272.18387866690665, + "y": 169.96429701350235, + "strokeColor": "#e03131", + "backgroundColor": "transparent", + "width": 129.9998779296875, + "height": 25, + "seed": 1542212183, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721390783931, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "sendTransfer", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "sendTransfer", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 1065, + "versionNonce": 698715482, + "index": "aF", + "isDeleted": false, + "id": "2xNUCVThpXTigfqtsGJHc", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 917.0283164259336, + "y": 393.53853015581706, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 750.9205799880971, + "height": 477.1872215999752, + "seed": 643800025, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "N_e9An2TnP5EegdA7TYu0", + "type": "arrow" + } + ], + "updated": 1721391148399, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 404, + "versionNonce": 472945562, + "index": "aG", + "isDeleted": false, + "id": "09p1k2GmKEc7_M8tez7hN", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 917.0283164259336, + "y": 360.00196576757037, + "strokeColor": "#e03131", + "backgroundColor": "transparent", + "width": 133.99989318847656, + "height": 25, + "seed": 1468066425, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [ + { + "id": "8HGAHjo9alsyXDCxeEhAp", + "type": "arrow" + } + ], + "updated": 1721391148399, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "onRecvPacket", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "onRecvPacket", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "text", + "version": 813, + "versionNonce": 357851674, + "index": "aH", + "isDeleted": false, + "id": "uifUVSpwEQeWvd8_O1w1x", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1989.0668437731438, + "y": 825.824601382853, + "strokeColor": "#e03131", + "backgroundColor": "transparent", + "width": 133.99989318847656, + "height": 25, + "seed": 1170029625, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721398431148, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "onRecvPacket", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "onRecvPacket", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 835, + "versionNonce": 192220890, + "index": "aI", + "isDeleted": false, + "id": "HYxBGdAxPhxx77rP-2_wP", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1979.7210283852673, + "y": 861.7445106177956, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 439.14638420461347, + "height": 209.64974254173208, + "seed": 1375318265, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "Eqhn1GBxEY7KAgrR903nW", + "type": "arrow" + }, + { + "id": "N_e9An2TnP5EegdA7TYu0", + "type": "arrow" + } + ], + "updated": 1721398431148, + "link": null, + "locked": false + }, + { + "type": "arrow", + "version": 929, + "versionNonce": 2133126534, + "index": "aJ", + "isDeleted": false, + "id": "sgKNMd6-7II77xbdG6qOX", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 903.8794591920116, + "y": 174.5109319008393, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 0.2013230555763812, + "height": 1139.696081087479, + "seed": 2100571513, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1721391263681, + "link": null, + "locked": false, + "startBinding": { + "elementId": "3YcAjui8eUFaxmbDcKayJ", + "focus": 0.2819110820952405, + "gap": 12.298242432567008 + }, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 0.2013230555763812, + 1139.696081087479 + ] + ] + }, + { + "type": "text", + "version": 397, + "versionNonce": 1137243034, + "index": "aL", + "isDeleted": false, + "id": "3YcAjui8eUFaxmbDcKayJ", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 878.1968563543343, + "y": 137.2126894682723, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 71.51995849609375, + "height": 25, + "seed": 1586837495, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [ + { + "id": "sgKNMd6-7II77xbdG6qOX", + "type": "arrow" + } + ], + "updated": 1721390853103, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "chain B", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "chain B", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "text", + "version": 503, + "versionNonce": 1662501574, + "index": "aM", + "isDeleted": false, + "id": "G3-gvgZsqMVqX_oz-iiFH", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1928.7981812626654, + "y": 137.2126894682723, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 69.85995483398438, + "height": 25, + "seed": 725312377, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721391270677, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "chain C", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "chain C", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 1962, + "versionNonce": 964280410, + "index": "aN", + "isDeleted": false, + "id": "8HGAHjo9alsyXDCxeEhAp", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 588.0200009252582, + "y": 399.47004149999134, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 303.0481639343741, + "height": 0.27236065526119546, + "seed": 1300355545, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1721391131179, + "link": null, + "locked": false, + "startBinding": { + "elementId": "-LqXV4Ju2E1Ik3GMk8X0k", + "focus": 0.9649361284756259, + "gap": 27.793259208028218 + }, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 303.0481639343741, + -0.27236065526119546 + ] + ] + }, + { + "type": "text", + "version": 472, + "versionNonce": 1393732358, + "index": "aO", + "isDeleted": false, + "id": "VnIAfK4FcRNB9hjkdBiZO", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0.0065641796763031834, + "x": 676.0564243364322, + "y": 364.80764648224823, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 115.25990295410156, + "height": 25, + "seed": 1286770201, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721391140541, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "packetAtoB", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "packetAtoB", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 3791, + "versionNonce": 1980879322, + "index": "aP", + "isDeleted": false, + "id": "N_e9An2TnP5EegdA7TYu0", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1680.9133377421076, + "y": 864.3694078026004, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 275.67427632090494, + "height": 2.593364124643017, + "seed": 1110419127, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1721398431148, + "link": null, + "locked": false, + "startBinding": { + "elementId": "2xNUCVThpXTigfqtsGJHc", + "focus": 0.9440017743888038, + "gap": 12.9644413280771 + }, + "endBinding": { + "elementId": "HYxBGdAxPhxx77rP-2_wP", + "focus": 0.9104963385077985, + "gap": 23.133414322254794 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 275.67427632090494, + 2.593364124643017 + ] + ] + }, + { + "type": "text", + "version": 795, + "versionNonce": 2003532166, + "index": "aQ", + "isDeleted": false, + "id": "xz1MNvMA9mfmqpo9OKP3G", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0.015723577377153575, + "x": 1764.7277546688324, + "y": 830.3558362693552, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 115.0198974609375, + "height": 25, + "seed": 1637453049, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721391172118, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "packetBtoC", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "packetBtoC", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "text", + "version": 1168, + "versionNonce": 473142938, + "index": "aR", + "isDeleted": false, + "id": "4WCvYeWRpdBoz-3Q4NnoS", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 929.690800505773, + "y": 1088.2019971727436, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 230.83981323242188, + "height": 100, + "seed": 310816825, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721391188999, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "retrieve packetAtoB\nwrite ack (packetAtoB)\n\ndelete packetAtoB", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "retrieve packetAtoB\nwrite ack (packetAtoB)\n\ndelete packetAtoB", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 622, + "versionNonce": 1232712538, + "index": "aS", + "isDeleted": false, + "id": "4Io5Rp0F6mIZqiKyi6t0N", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 917.4555736796583, + "y": 1075.3159194011434, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 325.53055656045603, + "height": 120.40440728691365, + "seed": 161621241, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "P5P9UeoVFMboMNjuA-9AK", + "type": "arrow" + }, + { + "id": "Eqhn1GBxEY7KAgrR903nW", + "type": "arrow" + } + ], + "updated": 1721391188999, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 798, + "versionNonce": 341849690, + "index": "aT", + "isDeleted": false, + "id": "IXOlt8Dp45562Zn5iqois", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 917.4555736796583, + "y": 1042.1592326995321, + "strokeColor": "#e03131", + "backgroundColor": "transparent", + "width": 247.27978515625, + "height": 25, + "seed": 110061111, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721391188999, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "onAcknowledgementPacket", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "onAcknowledgementPacket", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 1395, + "versionNonce": 1548656730, + "index": "aU", + "isDeleted": false, + "id": "Eqhn1GBxEY7KAgrR903nW", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1955.8554961071927, + "y": 1071.3470665084844, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 705.3140050141426, + "height": 4.436795705239774, + "seed": 827374745, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1721398431148, + "link": null, + "locked": false, + "startBinding": { + "elementId": "HYxBGdAxPhxx77rP-2_wP", + "focus": -0.9721401838478735, + "gap": 23.865532278074397 + }, + "endBinding": { + "elementId": "4Io5Rp0F6mIZqiKyi6t0N", + "focus": -0.958135027750018, + "gap": 7.555360852935905 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -705.3140050141426, + 4.436795705239774 + ] + ] + }, + { + "type": "text", + "version": 1075, + "versionNonce": 946209926, + "index": "aV", + "isDeleted": false, + "id": "yw0PWwV3nWEk41QKiIhyO", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 6.280976262094214, + "x": 1502.8577314573058, + "y": 1036.5200686073217, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 173.19985961914062, + "height": 25, + "seed": 1570375673, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721391303480, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "ack (packetBtoC)", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "ack (packetBtoC)", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 1239, + "versionNonce": 357107014, + "index": "aW", + "isDeleted": false, + "id": "P5P9UeoVFMboMNjuA-9AK", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 897.5759110554653, + "y": 1197.6542553507638, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 310.35420021721086, + "height": 3.0558842002553774, + "seed": 1318195577, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1721391321341, + "link": null, + "locked": false, + "startBinding": { + "elementId": "4Io5Rp0F6mIZqiKyi6t0N", + "focus": -0.9762618588252879, + "gap": 19.87966262419286 + }, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -310.35420021721086, + 3.0558842002553774 + ] + ] + }, + { + "type": "text", + "version": 1099, + "versionNonce": 597104986, + "index": "aX", + "isDeleted": false, + "id": "FkSCmHbUSF3emeF79Q69J", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 6.2797425472774595, + "x": 655.1772450696166, + "y": 1163.2352370104911, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 173.4398651123047, + "height": 25, + "seed": 1917942457, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721391251401, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "ack (packetAtoB)", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "ack (packetAtoB)", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "text", + "version": 461, + "versionNonce": 1181123930, + "index": "aZ", + "isDeleted": false, + "id": "tED5edHiPU164udhrVD29", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 917.0283164259336, + "y": 879.3899003587428, + "strokeColor": "#e03131", + "backgroundColor": "transparent", + "width": 147.49989318847656, + "height": 25, + "seed": 1841434455, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721391475066, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "no ack written!", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "no ack written!", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "text", + "version": 1183, + "versionNonce": 1221734042, + "index": "aa", + "isDeleted": false, + "id": "pSRus7Synn9o0xhodzzx0", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 319.89830364187833, + "y": 1217.053116418913, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 51.359954833984375, + "height": 25, + "seed": 885022647, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721391233370, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "no op", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "no op", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 641, + "versionNonce": 377834330, + "index": "ab", + "isDeleted": false, + "id": "jHYS_rN2WicEWEsWs4A38", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 307.6630768157636, + "y": 1204.1670386473127, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 260.88656550552963, + "height": 46.78595318915578, + "seed": 1663652055, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1721391233370, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 827, + "versionNonce": 557240346, + "index": "ac", + "isDeleted": false, + "id": "PT6crO9bjUcpODS5dcA3p", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 307.6630768157636, + "y": 1171.0103519457014, + "strokeColor": "#e03131", + "backgroundColor": "transparent", + "width": 247.27978515625, + "height": 25, + "seed": 1972837879, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721391233370, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "onAcknowledgementPacket", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "onAcknowledgementPacket", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 1052, + "versionNonce": 51421146, + "index": "b0b", + "isDeleted": false, + "id": "ZN8foweFftsQiJ9v6GG-5", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1967.88026675804, + "y": 175.54838993432872, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 0.2013230555763812, + "height": 1139.696081087479, + "seed": 44717594, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1721391293069, + "link": null, + "locked": false, + "startBinding": null, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 0.2013230555763812, + 1139.696081087479 + ] + ] + }, + { + "type": "arrow", + "version": 845, + "versionNonce": 522914650, + "index": "b0c", + "isDeleted": false, + "id": "otleiEczPEeoFdhofVq2_", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 575.6986717813893, + "y": 1453.99165110909, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 7.141516764452717, + "height": 1325.2279701053567, + "seed": 191803206, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1721391605189, + "link": null, + "locked": false, + "startBinding": { + "elementId": "RM7zJhNaCicQ-RxH90Hx-", + "focus": 0.10920725118350195, + "gap": 12.149791114464506 + }, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 7.141516764452717, + 1325.2279701053567 + ] + ] + }, + { + "type": "text", + "version": 1375, + "versionNonce": 764063046, + "index": "b0d", + "isDeleted": false, + "id": "rQtffJqtXGbFhpthMOo-2", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 928.3349014342682, + "y": 1688.933917709401, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 718.7401123046875, + "height": 450, + "seed": 564450950, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721398222119, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "if received tokens trace is prefixed by \"transfer/channelAToB\" {\n transfer tokens from escrow[channelBtoA] to forwarding[channelBtoA]\n} else {\n mint IBC vouchers to forwarding[channelBtoA]\n}\n\nsend packetBtoC{\n sender: forwarding[channelBtoA]\n receiver: chainC...\n}\n\nif sent tokens trace is prefixed by \"transfer/channelBToC\" {\n burn vouchers from forwarding[channelBtoA]\n} else {\n transfer tokens from forwarding[channelBtoA] to escrow[channelBtoC]\n}\n\nstore packetAtoB", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "if received tokens trace is prefixed by \"transfer/channelAToB\" {\n transfer tokens from escrow[channelBtoA] to forwarding[channelBtoA]\n} else {\n mint IBC vouchers to forwarding[channelBtoA]\n}\n\nsend packetBtoC{\n sender: forwarding[channelBtoA]\n receiver: chainC...\n}\n\nif sent tokens trace is prefixed by \"transfer/channelBToC\" {\n burn vouchers from forwarding[channelBtoA]\n} else {\n transfer tokens from forwarding[channelBtoA] to escrow[channelBtoC]\n}\n\nstore packetAtoB", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "text", + "version": 295, + "versionNonce": 1494092294, + "index": "b0e", + "isDeleted": false, + "id": "RM7zJhNaCicQ-RxH90Hx-", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 544.3509247576897, + "y": 1416.8418599946256, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 70.09996032714844, + "height": 25, + "seed": 890508742, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [ + { + "id": "otleiEczPEeoFdhofVq2_", + "type": "arrow" + } + ], + "updated": 1721391386965, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "chain A", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "chain A", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "text", + "version": 414, + "versionNonce": 1697366150, + "index": "b0f", + "isDeleted": false, + "id": "zAkLXu88_FnWJxIxHVi0W", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 286.6798265193436, + "y": 1496.7742492015136, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 263.75982666015625, + "height": 175, + "seed": 1859742982, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721391386965, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "send packetAtoB {\n sender: chainA...\n receiver: chainC...\n forwardingPath: {\n \"transfer/channelBtoC\"\n }\n}", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "send packetAtoB {\n sender: chainA...\n receiver: chainC...\n forwardingPath: {\n \"transfer/channelBtoC\"\n }\n}", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 314, + "versionNonce": 959305478, + "index": "b0h", + "isDeleted": false, + "id": "W0brwFWajXGedkh5jSqAh", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 272.3593724648556, + "y": 1485.046536084471, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 288.0428630503233, + "height": 197.54554923377296, + "seed": 330982278, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "EYCU59bcGM0yY9_7zS99M", + "type": "arrow" + } + ], + "updated": 1721391386965, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 259, + "versionNonce": 796675462, + "index": "b0i", + "isDeleted": false, + "id": "9YKuQ7YLqu5mQYcg2OyWh", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 272.3593724648556, + "y": 1449.5934675398557, + "strokeColor": "#e03131", + "backgroundColor": "transparent", + "width": 129.9998779296875, + "height": 25, + "seed": 1190134470, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721391386965, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "sendTransfer", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "sendTransfer", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 1161, + "versionNonce": 652520646, + "index": "b0j", + "isDeleted": false, + "id": "ZYWW3maO3Y4gM6KO-JusL", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 917.2038102238826, + "y": 1673.16770068217, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 750.9205799880971, + "height": 477.1872215999752, + "seed": 414169606, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "3Md7voHeufaQNWuPkH2v7", + "type": "arrow" + } + ], + "updated": 1721391386965, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 500, + "versionNonce": 1447605062, + "index": "b0k", + "isDeleted": false, + "id": "6b6gc4l3ETpzflmkGMlAM", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 917.2038102238826, + "y": 1639.6311362939236, + "strokeColor": "#e03131", + "backgroundColor": "transparent", + "width": 133.99989318847656, + "height": 25, + "seed": 1609992518, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [ + { + "id": "EYCU59bcGM0yY9_7zS99M", + "type": "arrow" + } + ], + "updated": 1721391386965, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "onRecvPacket", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "onRecvPacket", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "text", + "version": 917, + "versionNonce": 1400979846, + "index": "b0l", + "isDeleted": false, + "id": "Fyh3IF7aoHrMEG2TKd1KF", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1981.4535784228806, + "y": 2108.947302945244, + "strokeColor": "#e03131", + "backgroundColor": "transparent", + "width": 133.99989318847656, + "height": 25, + "seed": 203518086, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721398440253, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "onRecvPacket", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "onRecvPacket", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 1249, + "versionNonce": 51497754, + "index": "b0n", + "isDeleted": false, + "id": "0_WQp1XiXnnEWPvakU95Q", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 904.0549529899606, + "y": 1454.1401024271927, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 2.2800825183104507, + "height": 1336.6693473871323, + "seed": 41387782, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1721391611013, + "link": null, + "locked": false, + "startBinding": { + "elementId": "L-BH2oycGExYPTPNjcQkp", + "focus": 0.28282026169540886, + "gap": 12.298242432567122 + }, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 2.2800825183104507, + 1336.6693473871323 + ] + ] + }, + { + "type": "text", + "version": 493, + "versionNonce": 1104275334, + "index": "b0o", + "isDeleted": false, + "id": "L-BH2oycGExYPTPNjcQkp", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 878.3723501522832, + "y": 1416.8418599946256, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 71.51995849609375, + "height": 25, + "seed": 960280134, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [ + { + "id": "0_WQp1XiXnnEWPvakU95Q", + "type": "arrow" + } + ], + "updated": 1721391386965, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "chain B", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "chain B", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "text", + "version": 600, + "versionNonce": 1948439450, + "index": "b0p", + "isDeleted": false, + "id": "V0em9RQid1YsshTW2NoU1", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1928.9736750606144, + "y": 1416.8418599946256, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 69.85995483398438, + "height": 25, + "seed": 370802054, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [ + { + "id": "ibBezEs6ZMBff_zQs5kY4", + "type": "arrow" + } + ], + "updated": 1721391615405, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "chain C", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "chain C", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 2184, + "versionNonce": 1891179738, + "index": "b0q", + "isDeleted": false, + "id": "EYCU59bcGM0yY9_7zS99M", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 588.195494723207, + "y": 1679.0992120263445, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 303.0481639343741, + "height": 0.27236065526119546, + "seed": 1313627334, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1721391387172, + "link": null, + "locked": false, + "startBinding": { + "elementId": "W0brwFWajXGedkh5jSqAh", + "focus": 0.9649361284756256, + "gap": 27.793259208028076 + }, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 303.0481639343741, + -0.27236065526119546 + ] + ] + }, + { + "type": "text", + "version": 568, + "versionNonce": 5698694, + "index": "b0r", + "isDeleted": false, + "id": "hcnv2P1VMccbZXga3Ihtc", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0.0065641796763031834, + "x": 676.2319181343812, + "y": 1644.4368170086013, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 115.25990295410156, + "height": 25, + "seed": 1735447558, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721391386965, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "packetAtoB", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "packetAtoB", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 3998, + "versionNonce": 2012508570, + "index": "b0s", + "isDeleted": false, + "id": "3Md7voHeufaQNWuPkH2v7", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1681.0888315400566, + "y": 2144.00504226104, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 272.67427632090494, + "height": 2.5734363123119692, + "seed": 730096454, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1721391387172, + "link": null, + "locked": false, + "startBinding": { + "elementId": "ZYWW3maO3Y4gM6KO-JusL", + "focus": 0.9440017743888054, + "gap": 12.9644413280771 + }, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 272.67427632090494, + 2.5734363123119692 + ] + ] + }, + { + "type": "text", + "version": 891, + "versionNonce": 1109134086, + "index": "b0t", + "isDeleted": false, + "id": "oTAZSfgKxlBGR45JEtCBh", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0.015723577377153575, + "x": 1764.9032484667814, + "y": 2109.9850067957086, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 115.0198974609375, + "height": 25, + "seed": 484706950, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721391386965, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "packetBtoC", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "packetBtoC", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "text", + "version": 996, + "versionNonce": 494064922, + "index": "b0w", + "isDeleted": false, + "id": "MpYiaWdvAYvOo4n2pCRuA", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 917.6310674776073, + "y": 2219.7884032258853, + "strokeColor": "#e03131", + "backgroundColor": "transparent", + "width": 247.27978515625, + "height": 25, + "seed": 1779273798, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721391458354, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "onAcknowledgementPacket", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "onAcknowledgementPacket", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 2057, + "versionNonce": 130765018, + "index": "b0x", + "isDeleted": false, + "id": "lrbU8XgF0ilv3bAe90yZH", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1961.0907322739886, + "y": 2254.1539085562645, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 286.9462207254535, + "height": 2.6969505102097173, + "seed": 1807718278, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1721398452038, + "link": null, + "locked": false, + "startBinding": { + "elementId": "KWbGknRtIF4Je9g27kDgk", + "focus": -1.0648555439596428, + "gap": 19.0338254582 + }, + "endBinding": { + "elementId": "1yRqY9xPUXVqt9V-VV6c2", + "focus": -0.9299803073935413, + "gap": 7.3891439850493725 + }, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -286.9462207254535, + 2.6969505102097173 + ] + ] + }, + { + "type": "text", + "version": 1313, + "versionNonce": 998632794, + "index": "b0y", + "isDeleted": false, + "id": "vb_o7HkT18BthRdJJo3m-", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 6.280976262094214, + "x": 1740.860003527854, + "y": 2221.5047065029307, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 173.19985961914062, + "height": 25, + "seed": 1345238726, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721391535282, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "ack (packetBtoC)", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "ack (packetBtoC)", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 1757, + "versionNonce": 1153007494, + "index": "b0z", + "isDeleted": false, + "id": "XrQ-OzIJlfW0AtYf-n4CW", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 895.4123418568441, + "y": 2675.7817580137844, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 304.33740353601297, + "height": 0.07045303591075935, + "seed": 1878519302, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1721391571178, + "link": null, + "locked": false, + "startBinding": { + "elementId": "1yRqY9xPUXVqt9V-VV6c2", + "focus": -1.0245053530289139, + "gap": 24.512758391025955 + }, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + -304.33740353601297, + 0.07045303591075935 + ] + ] + }, + { + "type": "text", + "version": 1259, + "versionNonce": 1750693638, + "index": "b10", + "isDeleted": false, + "id": "4pScE4wr7Uz7tGiy6plMI", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 6.2797425472774595, + "x": 663.948625390083, + "y": 2636.2792980822765, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 173.4398651123047, + "height": 25, + "seed": 135806278, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721391599395, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "ack (packetAtoB)", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "ack (packetAtoB)", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "text", + "version": 570, + "versionNonce": 1384718790, + "index": "b11", + "isDeleted": false, + "id": "dtGr8tLZXr3N5YqYxCrP1", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 918.3683205692284, + "y": 2160.6900501944046, + "strokeColor": "#e03131", + "backgroundColor": "transparent", + "width": 147.49989318847656, + "height": 25, + "seed": 770483334, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721391465614, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "no ack written!", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "no ack written!", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "text", + "version": 1361, + "versionNonce": 1364363974, + "index": "b12", + "isDeleted": false, + "id": "74D0-xiw8ZjJDGGjoUxal", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 322.52561989624587, + "y": 2686.6985273177033, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 61.340003967285156, + "height": 25, + "seed": 1127359430, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721391589389, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "refund", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "refund", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 812, + "versionNonce": 144280134, + "index": "b13", + "isDeleted": false, + "id": "PTZBBJTzK8a2D886-p0CT", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 310.29039307013113, + "y": 2673.812449546103, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 260.88656550552963, + "height": 46.78595318915578, + "seed": 1778760454, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [], + "updated": 1721391577775, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 998, + "versionNonce": 180113798, + "index": "b14", + "isDeleted": false, + "id": "j8Atvv2w0yuXiYExyaV67", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 310.29039307013113, + "y": 2640.6557628444916, + "strokeColor": "#e03131", + "backgroundColor": "transparent", + "width": 247.27978515625, + "height": 25, + "seed": 2028235334, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721391577775, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "onAcknowledgementPacket", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "onAcknowledgementPacket", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "arrow", + "version": 1199, + "versionNonce": 1535885018, + "index": "b15", + "isDeleted": false, + "id": "ibBezEs6ZMBff_zQs5kY4", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1968.055760555989, + "y": 1455.177560460682, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 1.9992338467293393, + "height": 1324.8808925762319, + "seed": 1856713094, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 2 + }, + "boundElements": [], + "updated": 1721391615405, + "link": null, + "locked": false, + "startBinding": { + "elementId": "V0em9RQid1YsshTW2NoU1", + "focus": -0.11768980748794368, + "gap": 13.335700466056323 + }, + "endBinding": null, + "lastCommittedPoint": null, + "startArrowhead": null, + "endArrowhead": "arrow", + "points": [ + [ + 0, + 0 + ], + [ + 1.9992338467293393, + 1324.8808925762319 + ] + ] + }, + { + "type": "text", + "version": 1846, + "versionNonce": 1734341863, + "index": "b17", + "isDeleted": false, + "id": "rYcgj44Q9ycg_sbKPGb9i", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 933.134989975332, + "y": 2259.7976515360433, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 718.739990234375, + "height": 400, + "seed": 251475782, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721595832888, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "if sent tokens trace is prefixed by \"transfer/channelBToC\" {\n mint IBC vouchers to forwarding[channelBtoA]\n} else {\n transfer tokens from escrow[channelBtoC] to forwarding[channelBtoA]\n}\n\nretrieve packetAtoB\nif sent tokens trace is prefixed by \"transfer/channelBToA\" {\n burn IBC vouchers from forwarding[channelBtoA]\n} else { \n transfer tokens from forwarding[channelBtoA] to escrow[channelBtoA]\n}\n\nwrite error ack (packetAtoB)\n\ndelete packetAtoB", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "if sent tokens trace is prefixed by \"transfer/channelBToC\" {\n mint IBC vouchers to forwarding[channelBtoA]\n} else {\n transfer tokens from escrow[channelBtoC] to forwarding[channelBtoA]\n}\n\nretrieve packetAtoB\nif sent tokens trace is prefixed by \"transfer/channelBToA\" {\n burn IBC vouchers from forwarding[channelBtoA]\n} else { \n transfer tokens from forwarding[channelBtoA] to escrow[channelBtoA]\n}\n\nwrite error ack (packetAtoB)\n\ndelete packetAtoB", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 1269, + "versionNonce": 159900570, + "index": "b18", + "isDeleted": false, + "id": "1yRqY9xPUXVqt9V-VV6c2", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 919.9251002478702, + "y": 2248.937245537475, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 746.8302673156155, + "height": 421.4993359234997, + "seed": 1109548678, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "lrbU8XgF0ilv3bAe90yZH", + "type": "arrow" + }, + { + "id": "XrQ-OzIJlfW0AtYf-n4CW", + "type": "arrow" + } + ], + "updated": 1721391558425, + "link": null, + "locked": false + }, + { + "type": "text", + "version": 970, + "versionNonce": 1714102470, + "index": "b1A", + "isDeleted": false, + "id": "sGvqLevJTSKlQJ2bLFNVN", + "fillStyle": "solid", + "strokeWidth": 2, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1994.3967674333971, + "y": 2157.0275201708705, + "strokeColor": "#e03131", + "backgroundColor": "transparent", + "width": 288.41973876953125, + "height": 75, + "seed": 1648319386, + "groupIds": [], + "frameId": null, + "roundness": null, + "boundElements": [], + "updated": 1721398440253, + "link": null, + "locked": false, + "fontSize": 20, + "fontFamily": 1, + "text": "ERROR!\n\nwrite error ack (packetBtoC)", + "textAlign": "left", + "verticalAlign": "top", + "containerId": null, + "originalText": "ERROR!\n\nwrite error ack (packetBtoC)", + "autoResize": true, + "lineHeight": 1.25 + }, + { + "type": "rectangle", + "version": 932, + "versionNonce": 517412870, + "index": "b1C", + "isDeleted": false, + "id": "KWbGknRtIF4Je9g27kDgk", + "fillStyle": "solid", + "strokeWidth": 1, + "strokeStyle": "solid", + "roughness": 1, + "opacity": 100, + "angle": 0, + "x": 1980.1245577321888, + "y": 2141.26030290846, + "strokeColor": "#1e1e1e", + "backgroundColor": "transparent", + "width": 320.7643745091394, + "height": 106.15962645950245, + "seed": 2029829402, + "groupIds": [], + "frameId": null, + "roundness": { + "type": 3 + }, + "boundElements": [ + { + "id": "lrbU8XgF0ilv3bAe90yZH", + "type": "arrow" + } + ], + "updated": 1721398440253, + "link": null, + "locked": false + } + ], + "appState": { + "gridSize": null, + "viewBackgroundColor": "#ffffff" + }, + "files": {} +} \ No newline at end of file diff --git a/ibc/next/spec/app/ics-020-fungible-token-transfer/deprecated/source-and-sink-zones.png b/ibc/next/spec/app/ics-020-fungible-token-transfer/deprecated/source-and-sink-zones.png new file mode 100644 index 0000000000000000000000000000000000000000..1e77b983df1d22d94f024ce7e1c1cd225a5f2761 GIT binary patch literal 171848 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