Communication between different blockchains has always been an interesting and relevant problem. One of the most important applications that should be developed for blockchains is a mechanism that will allow an exchange of information between them. Since every blockchain has its own rules depending on the way it was designed, to enable this communication, a decentralized system that will ensure that the rules of both blockchains are respected is needed. Our project “Cosmos-SDK parachain development kit” is a valuable contribution to that.
The project has already been introduced. In short, during this project, we will build a functionality that allows anyone who has built a chain with the Cosmos SDK to turn that chain into a full Polkadot parachain. The purpose is to enable developers to host their existing Cosmos chain on Polkadot, use the security provided by the Polkadot Relay Chain and benefit from Polkadot’s interoperability stack.
Phase 1 of the development has been described in the previous article. Also, we successfully delivered the first milestone for the Web3 Foundation grant concerning Phase 2. This article describes the important updates that have been made during the new milestone.
Validators elections and consensus
The major modernizations that we have managed to finish are associated with the validatorselections andconsensus. It is a fascinating and somewhat tricky matter.
In both systems, validators’ elections are based on DPoS consensus variation: Nominated Proof-of-Stake and Bonded Proof-of-Stake. Although both Substrate and Cosmos use DPoS BFT consensuses, they have some differences. While Cosmos is based on Tendermint, Substrate works on a hybrid consensus (BABE or AURA) + GRANDPA.
The selection procedure in Substrate is bound to the Substrate token, and system stability depends on a token value and correct choice of validators. Cosmos also has a similar Delegated Proof of Stake system and its token. Still, validators are chosen for Tendermint by rules established by Cosmos: Cosmos just gives a list to Tendermint, and the latter uses it.
Staking during validators’ elections is one of the main cases where tokens are used. There is the first interesting point: in our case, Substrate is responsible for the consensus layer, but token and staking logic is defined in Cosmos. As a result, we needed to change the procedure of selecting validators in Substrate so that it will ‘trust’ validators chosen through Cosmos. In short, Substrate validators need to be elected according to the Cosmos staking system.
We faced several problems here (which have been successfully solved): different sign algorithms, different accounts, and address formats. To make everything work properly, we keep a list of Cosmos accounts and corresponding Substrate accounts on the Substrate side. Thus, Cosmos and Substrate validator addresses can be matched so that validators can be elected in Cosmos and participate in consensus in Substrate.
In addition to this, in Substrate consensuses, all validators are equal because of the NPoS election, but in Cosmos, validators’ weights in consensus depend on their stakes, so we need to use weighted voting in BABE and GRANDPA.
Сhange of validators in Substrate. There is a session pallet and the module that is attached to it, which is responsible for determining who can validate.
This pallet sends a list of validators to the session, and the latter passes it to the consensus modules that need it. We have created our own module that will provide session pallet lists.
Let’s dive deeper into matching validators. To provide matching Cosmos and Substrate accounts, we used the abci-pallet’s storage. It contains a few maps that allow that. CosmosAccounts maps Cosmos keys to Substrate keys while SubstrateAccounts does vice versa. Any Substrate user can register their Cosmos account. To do that, they should use insert_cosmos_account, and if they want to remove an existing account – remove_cosmos_account extrinsic. But there is a problem: the current version of insert_cosmos_account extrinsic doesn’t verify if a Substrate user really controls a corresponding Cosmos account. We plan to fix it later by adding a digital signature made by the Cosmos key to the extrinsic.
Validator update
Each validator is represented by pub_key and power, where power is an integer directly proportional to the stake. Cosmos informs Tendermint/ABCI pallet about changes in the list of validators using the validator_updates field in the response of EndBlock.
An additional database was added to the Substrate node, so now this DB can be accessed from both off-chain worker and Substrate runtime (an off-chain worker, where EndBlock is called, can’t write updates directly to Substrate storage; also, the off-chain worker’s storage doesn’t guarantee data safety after restarts). This DB allowed solving the problem of node crashes after restarts – Substrate calls InitChain each time that contradicts the requirement of Cosmos where InitChain must be called only once. When InitChain is called first, a special flag is set in DB that blocks repeated calls.
SessionManager trait implements validator updates. It has a method new_session that returns the list of ValidatorId. The pallets that use this validator list – Aura, BABE, GRANDPA – implement OneSessionHandler and process the received list in on_new_session.
Another interesting point is that the current version of the Substrate session pallet, in fact, supports weighted voting, but new_session returns only the list of validators without weights. At the same time, BABE and GRANDPA operate with authorities’ lists with weights, and the equal weights of all authorities from new_session are hardcoded in on_new_session methods.
In ABCI pallet, new_session gets the list of Cosmos validators for a corresponding block from DB using runtime interfaces and matches them with corresponding Substrate accounts registered through insert_cosmos_account extrinsic. The validators’ weights received from Cosmos are accessible in the pallet but can’t be used by consensus pallets because of the limitations described above.
We cannot update validators on each block (like Cosmos and Tendermint allow), but only every two blocks because of the limits for a maximum frequency of validator updates that Substrate has.
Scheme 1. Validator update
1. The offchain worker of ABCI pallet sends EndBlock request to Cosmos. Cosmos returns the response containing a new list of validators.
2. Offchain worker writes the list of Cosmos validators to the external DB.
3. When a new session begins, Session pallet calls new_session in the SessionManager implementation in ABCI pallet.
4. ABCI pallet uses runtime interface for interaction with the external DB.
5. ABCI pallet reads the list of Cosmos validators from the DB.
6. ABCI pallet converts the list of Cosmos validators to the list of Substrate validators using account matching.
7. ABCI pallet returns the list of Substrate validators to Session pallet.
8. Consensus pallets receive and update their lists of validators in on_new_session method.
Validator rewards
The current version of ABCI pallet deals only with the ideal case without forks (when all validators work honestly and sign each block).
Tendermint uses last_commit_info field to inform Cosmos about validators who signed a current block. It is more difficult to use the same approach with Substrate because GRANDPA finalizes not each block but a chain of blocks at once. Because of that, we cannot get the list of signers for each block.
A possible solution for this problem is to limit the maximum chain length in GRANDPA to one block. It will allow Substrate to interact with Cosmos more similar to the way the Tendermint does. It will also solve the fork resolution problem that Cosmos SDK doesn’t support. Simultaneously, it requires changes in the core pallets of Substrate that we’d like to avoid; it will also discard all benefits of GRANDPA chain validation. That’s why an idea of changing Cosmos’ reward module is preferable.Cosmos validators’ addresses are calculated using SHA256 hash function. (which is not natively supported by Substrate.) last_commit_info contains them. This implementation was imported to the ABCI pallet. As a result, validators participating in Substrate consensus will get rewards in Cosmos token.
Scheme 2. Validator reward
1. When BeginBlock is called, the offchain worker receives the list of active Substrate validators from the Session pallet.
2. Offchain worker converts the list of Substrate validators to the list of Cosmos validators using account matching.
3. Offchain worker converts Cosmos validators’ public keys to addresses and sends them to Cosmos node in the BeginBlock request.
4. Cosmos validators are rewarded by the staking module.
Nodes synchronization
One more update that has been done during this milestone is Nodes synchronization. The task was to modify the Cosmos launcher so that it will be able to start the Substrate node automatically, using special flags. But as it turned out, a typical Cosmos-Tendermint node is a single program where Cosmos doesn’t provide any logs (excluding a message about node launch), and Tendermint writes all logs directly to the console, and Cosmos doesn’t know about them. Simultaneously, Cosmos and Substrate nodes are two separate programs, and redirecting Substrate logs to Cosmos would require significant changes in Cosmos.
Substrate provides more valuable logs than Cosmos does. That’s why we decided to minimize changes in Cosmos. To do that, we created a script for running Cosmos-Substrate nodes (https://github.com/adoriasoft/polkadot_cosmos_integration/blob/master/run.sh), where the Cosmos node is launched in the background. We also added several flags into Substrate to make interaction with Cosmos more flexible. Docker images can also be used to launch both nodes.
Pallet subscription
Also, we provided the modernization that allows other Substrate pallets functionality to subscribe to our abci pallet like it’s done in the Session pallet. The trait SubscriptionManager contains two methods: on_check_tx and on_deliver_tx. The subscription mechanism allows other pallets to expand the check_tx and deliver_tx logic. They are called after the corresponding methods of the abci pallet. This approach is similar to the SessionManager and OneSessionHandler interactions.
Future steps
We plan to implement the following steps during the new milestone:
Fork resolution
In Tendermint, block production and finalization are a single process – forks can happen only in the case of the validators’ misbehavior. On the other hand, Substrate consensus divides this process into two parts: BABE\AURA for block production and GRANDPA for block finalization. This approach is faster but creates orphan blocks. So, Cosmos-Substrate nodes should detect forks, roll-back their state, and choose finalized branches. This difference in the fork’s occurrence is a critical issue to be solved.
Applications based on Cosmos SDK can’t work on top of blockchains without instant finality. It breaks the security of any Cosmos app that uses Substrate hybrid consensus where forks of non-finalized blocks are possible. This restriction includes both independent chains and parachains. To avoid changes in Substrate consensus, we propose modifying Cosmos SDK by adding roll-back mechanisms to process forks correctly.
To do that, we plan to:
- Add rollback mechanism to Cosmos SDK;
- Connect Cosmos rollback mechanisms with Substrate;
- Simulate an attack that causes a fork.
Governance + Runtime upgrade
Governance mechanisms in both systems allow changing system parameters. In Substrate they allow changing even the source code.
The referendum system controls governance mechanisms, and each change must be approved by token-based voting. Cosmos internal governance can work despite the consensus that has been used. We want to allow Cosmos users to manage not only the Cosmos part of their nodes but also the Substrate part.
We plan to:
- Allow Substrate parameter updates using Cosmos governance;
- Allow Substrate runtime updates using Cosmos governance.
Slashing
Slashing mechanisms are mechanisms that have been created to prevent or minimize validators’ misbehavior. Each validator has a deposit that can be slashed in case of malicious actions. There are Fishermen in Substrate and Hackers in Cosmos that send claims about validators’ misbehavior.
High-level misbehavior that can be difficult to detect automatically may require claims from users and voting for decisions. We believe that this case doesn’t depend on consensus and will work in Cosmos app with no changes. It is going to be enough to launch separate DPoS Cosmos-Substrate blockchains.
Another issue that has to be mentioned is the reward system. The essential component that ensures that native Cosmos reward works correctly is the fact that consensus can provide the list of signers for each block. But it doesn’t work with GRANDPA where a chain of blocks is finalized at once.
Conclusions
Our team did a great job on this milestone, and the results that have been obtained are a significant contribution to solving the described problem. We are planning to implement future steps during the next milestone and come one step closer to the final goal of the project.
Links
Project description:
https://github.com/adoriasoft/polkadot-cosmos-docs/blob/master/description.md
https://github.com/w3f/General-Grants-Program/blob/master/grants/speculative/Cosmos_SDK_parachain_development_kit_Phase_2.md
Previous articles:
https://adoriasoft.com/blog/adoriasoft-will-enable-chains-built-with-the-cosmos-sdk-to-be-a-polkadot-parachain/
https://adoriasoft.com/blog/blockchain-technologies-polkadot-vs-cosmos/