Changeover Procedure
Chains that were not initially launched as consumers of Interchain Security can still participate in the protocol and leverage the economic security of the provider chain. The process where a standalone chain transitions to being a replicated consumer chain is called the changeover procedure and is part of the interchain security protocol. After the changeover, the new consumer chain will retain all existing state, including the IBC clients, connections and channels already established by the chain.
The relevant protocol specifications are available below:
Overview
Standalone to consumer changeover procedure can roughly be separated into 4 parts:
1. ConsumerAddition proposal submitted to the provider
chain
The proposal is equivalent to the "normal" ConsumerAddition proposal submitted by new consumer chains.
However, here are the most important notes and differences between a new consumer chain and a standalone chain performing a changeover:
chain_id
must be equal to the standalone chain idinitial_height
field has additional rules to abide by:
{
...
"initial_height" : {
// must correspond to current revision number of standalone chain
// e.g. stride-1 => "revision_number": 1
"revision_number": 1,
// must correspond to a height that is at least 1 block after the upgrade
// that will add the `consumer` module to the standalone chain
// e.g. "upgrade_height": 100 => "revision_height": 101
"revision_height": 1,
},
...
}
RevisionNumber: 0, RevisionHeight: 111
-
genesis_hash
can be safely ignored because the chain is already running. A hash of the standalone chain's initial genesis may be used -
binary_hash
may not be available ahead of time. All chains performing the changeover go through rigorous testing - if bugs are caught and fixed the hash listed in the proposal may not be the most recent one. -
spawn_time
listed in the proposal MUST be before theupgrade_height
listed in the upgrade proposal on the standalone chain.
spawn_time
must occur before the upgrade_height
on the standalone chain is reached because the provider
chain must generate the ConsumerGenesis
that contains the validator set that will be used after the changeover.
-
unbonding_period
must correspond to the value used on the standalone chain. Otherwise, the clients used for the ccv protocol may be incorrectly initialized. -
distribution_transmission_channel
should be set.
Populating distribution_transmission_channel
will enable the standalone chain to reuse one of the existing channels to the provider for consumer chain rewards distribution. This will preserve the ibc denom
that may already be in use.
If the parameter is not set, a new channel will be created.
-
ccv_timeout_period
has no important notes -
transfer_timeout_period
has no important notes -
consumer_redistribution_fraction
has no important notes -
blocks_per_distribution_transmission
has no important notes -
historical_entries
has no important notes
2. upgrade proposal on standalone chain
The standalone chain creates an upgrade proposal to include the interchain-security/x/ccv/consumer
module.
The upgrade height in the proposal should correspond to a height that is after the spawn_time
in the consumer addition proposal submitted to the provider
chain.
Otherwise, the upgrade is indistinguishable from a regular on-chain upgrade proposal.
3. spawn time is reached
When the spawn_time
is reached on the provider
it will generate a ConsumerGenesis
that contains the validator set that will supersede the standalone
validator set.
This ConsumerGenesis
must be available on the standalone chain during the on-chain upgrade.
4. standalone chain upgrade
Performing the on-chain upgrade on the standalone chain will add the ccv/consumer
module and allow the chain to become a consumer
of Interchain Security.
The ConsumerGenesis
must be exported to a file and placed in the correct folder on the standalone chain before the upgrade.
The file must be placed at the exact specified location, otherwise the upgrade will not be executed correctly.
Usually the file is placed in $NODE_HOME/config
, but the file name and the exact directory is dictated by the upgrade code on the standalone
chain.
- please check exact instructions provided by the
standalone
chain team
After the genesis.json
file has been made available, the process is equivalent to a normal on-chain upgrade. The standalone validator set will sign the next couple of blocks before transferring control to provider
validator set.
The standalone validator set can still be slashed for any infractions if evidence is submitted within the unboding_period
.
Notes
The changeover procedure may be updated in the future to create a seamless way of providing the validator set information to the standalone chain.
Onboarding Checklist
This onboarding checklist is slightly different from the one under Onboarding
Additionally, you can check the testnet repo for a comprehensive guide on preparing and launching consumer chains.
1. Complete testing & integration
- test integration with gaia
- test your protocol with supported relayer versions (minimum hermes 1.4.1)
- test the changeover procedure
- reach out to the ICS team if you are facing issues
2. Create an Onboarding Repository
To help validators and other node runners onboard onto your chain, please prepare a repository with information on how to run your chain.
This should include (at minimum):
- genesis.json with CCV data (after spawn time passes). Check if CCV data needs to be transformed (see Transform Consumer Genesis)
- information about relevant seed/peer nodes you are running
- relayer information (compatible versions)
- copy of your governance proposal (as JSON)
- a script showing how to start your chain and connect to peers (optional)
- take feedback from other developers, validators and community regarding your onboarding repo and make improvements where applicable
Example of such a repository can be found here.
3. Submit a ConsumerChainAddition Governance Proposal to the provider
Before you submit a ConsumerChainAddition
proposal, please provide a spawn_time
that is before the upgrade_height
of the upgrade that will introduce the ccv module
to your chain.
If the spawn_time
happens after your upgrade_height
the provider will not be able to communicate the new validator set to be used after the changeover.
Additionally, reach out to the community via the forum to formalize your intention to become an ICS consumer, gather community support and accept feedback from the community, validators and developers.
- determine your chain's spawn time
- determine consumer chain parameters to be put in the proposal
- take note to include a link to your onboarding repository
Example of a consumer chain addition proposal (compare with the ConsumerAdditionProposal in the ICS Provider Proposals section for chains that launch as consumers):
// ConsumerAdditionProposal is a governance proposal on the provider chain to spawn a new consumer chain or add a standalone chain.
// If it passes, then a subset (i.e., depends on `top_N` and on the power shaping parameters) of validators on the provider chain are expected
// to validate the consumer chain at spawn time. It is recommended that spawn time occurs after the proposal end time and that it is
// scheduled to happen before the standalone chain upgrade that sill introduce the ccv module.
{
// Title of the proposal
"title": "Changeover Standalone chain",
// Description of the proposal
// format the text as a .md file and include the file in your onboarding repository
"description": ".md description of your chain and all other relevant information",
// Proposed chain-id of the new consumer chain.
// Must be unique from all other consumer chain ids of the executing provider chain.
"chain_id": "standalone-1",
// Initial height of new consumer chain.
"initial_height" : {
// must correspond to current revision number of standalone chain
// e.g. standalone-1 => "revision_number": 1
"revision_number": 1,
// must correspond to a height that is at least 1 block after the upgrade
// that will add the `consumer` module to the standalone chain
// e.g. "upgrade_height": 100 => "revision_height": 101
"revision_number": 1,
},
// Hash of the consumer chain genesis state without the consumer CCV module genesis params.
// => not relevant for changeover procedure
"genesis_hash": "d86d756e10118e66e6805e9cc476949da2e750098fcc7634fd0cc77f57a0b2b0",
// Hash of the consumer chain binary that should be run by validators on standalone chain upgrade
// => not relevant for changeover procedure as it may become stale
"binary_hash": "376cdbd3a222a3d5c730c9637454cd4dd925e2f9e2e0d0f3702fc922928583f1",
// Time on the provider chain at which the consumer chain genesis is finalized and all validators
// will be responsible for starting their consumer chain validator node.
"spawn_time": "2023-02-28T20:40:00.000000Z",
// Unbonding period for the consumer chain.
// It should should be smaller than that of the provider.
"unbonding_period": 86400000000000,
// Timeout period for CCV related IBC packets.
// Packets are considered timed-out after this interval elapses.
"ccv_timeout_period": 259200000000000,
// IBC transfer packets will timeout after this interval elapses.
"transfer_timeout_period": 1800000000000,
// The fraction of tokens allocated to the consumer redistribution address during distribution events.
// The fraction is a string representing a decimal number. For example "0.75" would represent 75%.
// The reward amount distributed to the provider is calculated as: 1 - consumer_redistribution_fraction.
"consumer_redistribution_fraction": "0.75",
// BlocksPerDistributionTransmission is the number of blocks between IBC token transfers from the consumer chain to the provider chain.
// eg. send rewards to the provider every 1000 blocks
"blocks_per_distribution_transmission": 1000,
// The number of historical info entries to persist in store.
// This param is a part of the cosmos sdk staking module. In the case of
// a ccv enabled consumer chain, the ccv module acts as the staking module.
"historical_entries": 10000,
// The ID of a token transfer channel used for the Reward Distribution
// sub-protocol. If DistributionTransmissionChannel == "", a new transfer
// channel is created on top of the same connection as the CCV channel.
// Note that transfer_channel_id is the ID of the channel end on the consumer chain.
// it is most relevant for chains performing a standalone to consumer changeover
// in order to maintain the existing ibc transfer channel
"distribution_transmission_channel": "channel-123" // NOTE: use existing transfer channel if available
// Corresponds to the percentage of validators that have to validate the chain under the Top N case.
// For example, 53 corresponds to a Top 53% chain, meaning that the top 53% provider validators by voting power
// have to validate the proposed consumer chain. top_N can either be 0 or any value in [50, 100].
// A chain can join with top_N == 0 as an Opt In chain, or with top_N ∈ [50, 100] as a Top N chain.
"top_N": 95,
// Corresponds to the maximum power (percentage-wise) a validator can have on the consumer chain. For instance, if
// `validators_power_cap` is set to 32, it means that no validator can have more than 32% of the voting power on the
// consumer chain. Note that this might not be feasible. For example, think of a consumer chain with only
// 5 validators and with `validators_power_cap` set to 10%. In such a scenario, at least one validator would need
// to have more than 20% of the total voting power. Therefore, `validators_power_cap` operates on a best-effort basis.
"validators_power_cap": 0,
// Corresponds to the maximum number of validators that can validate a consumer chain.
// Only applicable to Opt In chains. Setting `validator_set_cap` on a Top N chain is a no-op.
"validator_set_cap": 0,
// Corresponds to a list of provider consensus addresses of validators that are the ONLY ones that can validate
// the consumer chain.
"allowlist": [],
// Corresponds to a list of provider consensus addresses of validators that CANNOT validate the consumer chain.
"denylist": []
}
As seen in the ConsumerAdditionProposal
example above, the changeover procedure can be used together with Partial Set Security.
This means, that a standalone chain can choose to only be validated by some of the validators of the provider chain by setting top_N
appropriately, or by
additionally setting a validators-power cap, validator-set cap, etc. by using the power-shaping parameters.
3. Submit an Upgrade Proposal & Prepare for Changeover
This proposal should add the ccv consumer
module to your chain.
- proposal
upgrade_height
must happen afterspawn_time
in theConsumerAdditionProposal
- advise validators about the exact procedure for your chain and point them to your onboarding repository
4. Upgrade time 🚀
- after
spawn_time
, requestConsumerGenesis
from theprovider
and place it in<CURRENT_USER_HOME_DIR>/.sovereign/config/genesis.json
- upgrade the binary to the one listed in your
UpgradeProposal
The chain starts after at least 66.67% of standalone voting power comes online. The consumer chain is considered interchain secured once the "old" validator set signs a couple of blocks and transfers control to the provider
validator set.
- provide a repo with onboarding instructions for validators (it should already be listed in the proposal)
- genesis.json after
spawn_time
obtained fromprovider
(MUST contain the initial validator set) - maintenance & emergency contact info (relevant discord, telegram, slack or other communication channels)