cosmos / interchain-security

Interchain Security is an open sourced IBC application which allows cosmos blockchains to lease their proof-of-stake security to one another.
https://cosmos.github.io/interchain-security/
Other
156 stars 126 forks source link

Add a flag to disable validator set updates in staking module (for cross-chain validation) #15

Closed cmwaters closed 2 years ago

cmwaters commented 3 years ago

Summary

The upcoming Cross-Chain Validation module uses IBC to take validator updates from a parent chain and pass them through to the child chain. This therefore will require disabling validator set updates in the staking module.

Problem Definition

Cross chain validation (as part of Interchain Security) allows a chain to start up using the validator set of a parent chain. However, these child chains may want to issue their own token and have their own sovereign governance system. It may seem intuitive at first to simply remove the staking module, however, governance uses the staking module to gauge voting power. There are therefore a few ways to solve this:

  1. Implement custom tally function logic that can instead query the banking module and derive the voting power based on how many tokens an account has. This has the drawback that users don't have to stake tokens over a period of time which given the current governance logic means that someone can buy a million tokens, vote on a proposal and then sell them afterwards.
  2. If a chain didn't want its own sovereign governance system, we could use Interchain Accounts to allow proposals for a child chain to be submitted and voted on the parent chain then execute the messages through IBC on that child chain. However, we feel that an integral part of the Interchain security value offering is that child chains still have their own governance token.
  3. Extend the groups module to implement a staking based group. This alongside the groups/gov alignment work would allow the issuance of a gov token this group could then use the gov module to propose, vote and execute messages. This is perhaps the ideal solution in the long run but we're still far off from this happening.
  4. The solution we think is best due to its quick small incision is to keep the staking module but pass a boolean flag when initializing the keeper that effectively puts the staking module in shadow mode. In this mode, it still has a staking group that is paired with the governance module but the staking group isn't in any way connected to the validator set. The change means that the validator set updates calculated here: https://github.com/cosmos/cosmos-sdk/blob/148451b51c4af248ba3701691ad261e4913dfa91/x/staking/keeper/val_state_change.go#L27 aren't returned in the EndBlocker when the boolean flag is true.

It's important to walkthrough what the behavior of such a child chain system. Having this shadow staking module means that staking the chains native token can be used to acquire governing power. On a child chain, a node becoming a validator essentially means they are staking away their tokens to be able to vote. Their staked tokens can't be slashed (the slashing module doesn't exist) but they can potentially earn rewards for being a governance member. In the same manner as it is normally, a governing member could also delegate their voting power to another member and that member could also charge commission.

cc @okwme


For Admin Use

alexanderbez commented 3 years ago

@cmwaters note (1) is already being worked on because it's needed for a host of other reasons. So I suggest we just piggyback off of that work if possible.

Re your drawback for (1), that only applies of the tally logic uses the native token to determine "weight". Can't you use the parent chain's staking token instead? Or some combo of the two? Regardless, this sounds like a problem for the app to figure out.

cmwaters commented 3 years ago

Can't you use the parent chain's staking token instead?

But this means that the child chain loses its sovereignty. I'm under the impression that this is an important characteristic for child chains to still have.

(1) was initially started by Sikka AFAIK but I don't know what the current status of this is.

alexanderbez commented 3 years ago

There's an open PR for it. Why does it lose sovereignty?

cmwaters commented 3 years ago

Well it's controlled by the members of the parent chain. My impression was that these child chains want to be able to issue their own tokens and have its invested members be able to dictate the direction of the chain via governance.

alexanderbez commented 3 years ago

Yes, the child chain can/will issue it's own tokens, but the tally logic can still take into account the paren chain's token for power. I'm sure a solution can be thought of. Having x/staking not emit validator set updates just seems like a code-smell.

Also, there is no need to modify x/staking in the SDK. To achieve what you're describing can easily be done by an app by simply "extending" or embedding x/staking and overriding the ABCI's EndBlock method to be a no-op.

jtremback commented 3 years ago

I'm not sure this really makes sense to me. Governance power is derived from validation power. It sounds to me like the governance votes you are describing are essentially meaningless and that nobody voting has the actual power to do anything.

cmwaters commented 3 years ago

Having x/staking not emit validator set updates just seems like a code-smell.

Yeah I certainly don't disagree with it. I would label this solution as more of a short-term thing. There are a few couplings in the code i.e. governance and staking (and even staking to being a validator) which have aged poorly and paired with the introduction of groups means that a more clean design needs to be thought of in the long run. I'm still skeptical about custom tally functions being able to solve this use case. I'm happy to jump on a call to go through these options. It could be that we require the child chains to just fork the staking module for the time being.

mpoke commented 3 years ago

Since the objective is to eventually support on the child chain a mixed validator set (both local and remote), I would assume that a long term solution will allow multiple modules to update the validator set. This can be done through some kind of a weight function to determine the relative power (based on token value and staked amount). However, this implies changing the core of Cosmos SDK: https://github.com/cosmos/cosmos-sdk/blob/7043dde0716289f97d095f753b2049e5549d851d/types/module/module.go#L473.

Also, I think the way governance works on the child chain should be configurable. I see the following realistic scenarios: