Validator’s Note 12 — A BTS Look at Neutron’s Launch (ENG)

Youngbin Park
DSRV
Published in
8 min readMay 12, 2023

Disclaimer: This article is for informational purposes only and should not be taken as financial advice. No information contained within this article is a recommendation to invest in any of the assets mentioned. All investors are advised to thoroughly conduct their own research before making any financial decisions.

It’s official! Neutron has launched, becoming the first consumer chain to leverage the security of the Cosmos Hub, a smart contract platform that allows users to deploy apps freely. This was made possible through ICS (Interchain Security), a feature that enables highly secure provider chains to share security with other blockchains called consumer chains via a shared validator set. ICS’s first phase, Replicated Security, was set in motion by the last v9 Lambda upgrade on Cosmos Hub.

Last year, Cosmos Hub hosted the Game of Chains, an incentivized testnet program to test ICS functionality. Since then, various bug fixes and feature additions have been made through the RS (Replicated Security) testnet, which also served as rehearsal grounds for launch. DSRV participated in both the GoC and RS testnet to get a feel for the new features and help test them out.

Today, we’re going to take a look at the process of launching a consumer chain via Neutron.

Passing Governance

Source: https://www.mintscan.io/cosmos/proposals/792

The current phase, Replicated Security, requires every Cosmos Hub active validator to run all consumer chains or risk being slashed. If spam chains become consumer chains, this increases the burden and risk for operators. So to prevent this, all consumer chains must be approved via Cosmos Hub governance. Neutron has also passed Proposal #792 (Launch Neutron on Replicated Security), allowing it to be launched as a new consumer chain on Cosmos. This proposal contains information about the Neutron chain, such as network variables, chain id, and spawn time.

- Chain Id : neutron-1
...
- Spawn Time : 2023-05-08T11:00:00Z
- Transfer Timeout Period: 3600s
- Unbonding Period: 1728000s

CCV Channel Initialization

A little background

In order for a consumer chain to leverage the security of a provider chain, it must first create a CCV (Cross Chain Validation) channel. The CCV channel then becomes the conduit for sending and receiving VSC (Validator Set Change) packets and slashing packets. The former announce voting power changes to the provider chain’s validators, while the latter allow the consumer chain to slash errant validators. CCV channels play an important role in consumer chains, so unlike token transfers with multiple IBC channels, only one CCV channel can be created per consumer chain.

Source: https://github.com/cosmos/ibc/blob/8d9d3b6fe7309b034df8457760b3bbd11d24b8e1/spec/app/ics-028-cross-chain-validation/overview_and_basic_concepts.md

The process of initializing a CCV channel for a new consumer chain looks like the above.

  1. After the proposal’s Spawn Time has passed, the provider chain is triggered to create a client for the consumer chain. Based on the state of the CCV consumer parameter, validator set, etc. at the time the Spawn Time is reached (as well as the chain id in the proposal), the provider chain creates a Client in order to create a CCV channel with Neutron.
  2. The provider chain then creates a CCV genesis state containing a client state, consensus state, and set of validators from the provider chain. Validators check that everyone has the same CCV genesis state, and query this to manually add the CCV genesis state to the genesis file of the consumer chain (which has an empty CCV genesis state). Validators then start the chain using the genesis file and create clients. While validators can make blocks on the consumer chain at this stage, it technically doesn’t count as shared security yet because the consumer chain can’t receive packets from the provider chain.
  3. If the block is successfully created, the next step is to connect the CCV channel through the relayer: first, the relayer connects the RPCs of both chains through a connection handshake. After that, the CCV channel handshake takes place through four messages (transactions) that a relayer sends. This is similar to the existing IBC specification (ICS-04), but requires an additional step to verify that the client of the channel the provider chain wants to connect to is a registered (whitelisted) client of the consumer chain. These messages also include a proof that the previous steps worked correctly.

In the case of Neutron

Let’s take a look at how this actually happened on Neutron and the Cosmos Hub. Neutron’s Spawn Time was 2023–05–08 11:00 UTC, so the provider chain created the client and CCV genesis state at that time. However, Neutron actually started the chain on 2023–05–11 15:00 UTC (Genesis), and the CCV channel connection through the relayer was made a day later around 2023–05–12 15:00 UTC.

In the CCV channel connection process, the relayer first sent an OnChainOpenInit message to Neutron (consumer chain), which verified that the primary client associated with this channel was a client of the Cosmos Hub (provider chain).

Source: https://www.mintscan.io/neutron/txs/CEADBAB3268FF2264CB6B84EC5C1C542E35A589D5F0C115CE542843B7FFC3C54?height=6527
3:44PM INF client state updated client-id=07-tendermint-0 height=4-15255239 module=x/ibc/client
3:44PM INF created new capability module=ibc name=capabilities/ports/consumer/channels/channel-0
3:44PM INF claimed capability capability=6 module=ccvconsumer name=capabilities/ports/consumer/channels/channel-0
3:44PM INF channel state updated channel-id=channel-0 module=x/ibc/channel new-state=INIT port-id=consumer previous-state=NONE
3:44PM INF burned tokens from module account amount=4927untrn from=cons_redistribute module=x/bank
3:44PM INF executed block height=6527 module=state num_invalid_txs=0 num_valid_txs=1

Then the relayer sent OnChainOpenTry to the Cosmos Hub, providing Neutron’s chain id to verify 1) that the client was a registered (whitelisted) client, and 2) that no channel with that chain id was already connected.

Source: https://www.mintscan.io/cosmos/txs/E81128D059427C3B391345A50F44BE1EB57322A0EA3F3601C67F33240B632F39?height=15255243
3:44PM INF client state updated client-id=07-tendermint-1119 height=1-6528 module=x/ibc/client
3:44PM INF created new capability module=ibc name=capabilities/ports/provider/channels/channel-568
3:44PM INF claimed capability capability=572 module=provider name=capabilities/ports/provider/channels/channel-568
3:44PM INF channel state updated channel-id=channel-568 module=x/ibc/channel new-state=TRYOPEN port-id=provider previous-state=NONE
3:44PM INF VSCPacket enqueued: chainID=neutron-1 len unbonding ops=0 len updates=3 module=x/ibc-provider vscID=784743
3:44PM INF executed block height=15255243 module=state num_invalid_txs=0 num_valid_txs=7

Next, Neutron received an OnChainOpenAck and created the CCV channel on its end.

Source: https://www.mintscan.io/neutron/txs/646D48A56AF6A5B98551A7ED296786D8C388D8A3519765E12DC2D2E7102C1D8B?height=6530
3:45PM INF client state updated client-id=07-tendermint-0 height=4-15255244 module=x/ibc/client
3:45PM INF channel state updated channel-id=channel-0 module=x/ibc/channel new-state=OPEN port-id=consumer previous-state=STATE_OPEN
3:45PM INF created new capability module=ibc name=capabilities/ports/transfer/channels/channel-1
3:45PM INF claimed capability capability=7 module=transfer name=capabilities/ports/transfer/channels/channel-1
3:45PM INF channel state updated channel-id=channel-1 module=x/ibc/channel new-state=INIT port-id=transfer previous-state=NONE
3:45PM INF burned tokens from module account amount=5118untrn from=cons_redistribute module=x/bank
3:45PM INF executed block height=6530 module=state num_invalid_txs=0 num_valid_txs=1

The Cosmos Hub then received an OnChainOpenConfirm message and a CCV channel was finally created on the hub side. Once the channel was created, all VSC packets started being sent. However, since the Neutron chain was kickstarted about 2 days later than the actual on-chain recorded Spawn Time (and the relayers connected about 3 days later), it took over 3 hours to send over 14000 VSC packets that were pending on the Cosmos Hub.

The validator key allowing consumer chain validators to sign blocks can be the same as that of the provider chain, or it can alternatively be changed through the key-assignment function on the provider chain. However, if changed after spawn time, said validator must participate in the consensus of the consumer chain with the old validator key until the VSC packet update. This is because the CCV genesis state has already been created with the validator key of the consumer chain at spawn time. Once the VSC packet is updated to the consumer chain, the validator must use the changed validator key.

That being said, since it was unclear when the pending VSC packets would be updated, the recommended solution was to instead run two Neutron nodes with both pre and post-change validator keys. This allowed validators who changed their validator keys after spawn time to participate in consensus uninterrupted from Genesis.

Source: https://www.mintscan.io/cosmos/txs/7CF75E20752777643BDD48AD3EACF3B75817B0E818BB018197AB3483842064E7?height=15255249
3:45PM INF client state updated client-id=07-tendermint-1119 height=1-6531 module=x/ibc/client
3:45PM INF channel state updated channel-id=channel-568 module=x/ibc/channel new-state=OPEN port-id=provider previous-state=TRYOPEN
3:45PM INF created new capability module=ibc name=capabilities/ports/transfer/channels/channel-569
3:45PM INF claimed capability capability=573 module=transfer name=capabilities/ports/transfer/channels/channel-569
3:45PM INF channel state updated channel-id=channel-569 module=x/ibc/channel new-state=TRYOPEN port-id=transfer previous-state=NONE
3:45PM INF packet sent dst_channel=channel-0 dst_port=transfer module=x/ibc/channel sequence=106846 src_channel=channel-391 src_port=transfer
3:45PM INF IBC fungible token transfer amount=6652180 module=x/ibc-transfer receiver=stride1pczxmqaw2tgete03r6jwk7uvyy4355skhdcuur sender=cosmos1pczxmqaw2tgete03r6jwk7uvyy4355sk5xcqg0 token=uatom
3:45PM INF packet sent dst_channel=channel-0 dst_port=consumer module=x/ibc/chan
...
3:45PM INF packet sent dst_channel=channel-0 dst_port=consumer module=x/ibc/channel sequence=14508 src_channel=channel-568 src_port=provider
3:45PM INF packet sent dst_channel=channel-0 dst_port=consumer module=x/ibc/channel sequence=14509 src_channel=channel-568 src_port=provider
3:45PM INF Ensure peers module=pex numDialing=0 numInPeers=40 numOutPeers=10 numToDial=0
3:45PM INF executed block height=15255249 module=state num_invalid_txs=0 num_valid_txs=4

Although not shown in the figure above, the relayer also sends an UpdateClient message along with the four transactions. The UpdateClient message contains the status of the consumer chain and the signatures of the validators. While the above process only verifies the client using the chain id, the UpdateClient message prevents spam chains or malicious relayers (with an incorrect set of validators) from trying to fool the provider chain.

Once the CCV channel is created and the necessary packets can be sent and received, the consumer chain is said to be in a state of shared security. And that’s how Neutron was recently launched as the first successful consumer chain!

As a validator, we’ve been avidly following all the progress and are very excited to finally see the first consumer chain successfully launched. Starting with Neutron, our team looks forward to seeing more meaningful consumer chains diversifying the Cosmos Hub ecosystem.

Written by
Youngbin Park, Research Engineer, DSRV Validator Team (Twitter @bin0_0bin)
Heejin Lee, Software Engineer and Validator, DSRV Validator Team (Twitter @heeheejin)

Edited by
Domitille Colin, Brand Communications Manager (Twitter domitille_marie)

--

--