osmosis-labs / mesh-security

Other
66 stars 10 forks source link

Implement Slashing #11

Closed ethanfrey closed 1 year ago

ethanfrey commented 1 year ago

TODO:

Extra issues:

jtremback commented 1 year ago

Work underway in Interchain Security, probably reusable

https://github.com/cosmos/interchain-security/pull/1128/files#diff-655d4a7e003e101281bc9490676d87f4b44c177da997cc3caa48a0b75986bc21

maurolacy commented 1 year ago

OK, after discussing about this, I think we now have a good understanding of the requirements and design decisions around cross-slashing. Here are the salient points:

Control channel: We can hook into the evidence module to receive a callback on the Consumer side:

https://github.com/cosmos/cosmos-sdk/blob/v0.47.4/x/evidence/abci.go#L24

We then pass the evidence as part of the mesh-security protocol / channel. Otherwise we would need deep chain integration on the Provider side. This builds upon the assumption that the control channel, that is, the Consumer implementation of mesh security, can be fully trusted. I would say, Providers should trust that, but would want to verify the evidence nevertheless.

Evidence verification: For verifying the evidence on the Provider side, we would need the Consumer's validator set with the validator pubkeys, at the evidence height. That means / implies that we need to store or have access to the historical validator set. At least for the unbonding period, which is typically 21 days. This means either storing the validator set updates as part of the control channel protocol, which is already in planning (https://github.com/osmosis-labs/mesh-security/issues/88) or accessing the historical validator set or part of it on demand. If we can have a reliable way to query for the historical Consumer validator set, that would be a good option to storing the historical validator set changes, which will take significant storage, and cannot or is not easy to prune.

Governance step: A governance step during the slashing evidence handling is not a good idea. The governance would need to happen on the Provider side to be effective, and there are no involved or interested parties there. The Provider's validators are typically not involved in the cross staking process. The cross-delegators are usually too detached from the process, to be involved in voting. A proposal also would have to be automated, and voting on it would be difficult / unclear.

So, a fully automated, Provider verifiable implementation, that hooks on the evidence module of the Consumer, and doesn't involve governance (besides the granting of the required permissions) looks like the way to go.

@alpe please take a look and comment back if I'm missing something.

maurolacy commented 1 year ago

A couple more points.

Slashing's impact: The sensible / delicate issue with cross slashing is, that a Consumer could be affecting the Provider's native funds / voting power. When slashing a cross-delegator that is at the same time fully delegated natively, some of the funds would need to be unbonded, for the slashing (burning) to proceed. One one side, that will require a kind of immediate unbonding mechanism. Which will require permissions (through chain governance, typically) on the vault contract executing the slashing. On the other side, that would be impacting the Provider's native voting power.

Perhaps a mechanism or mechanisms can be built to work around this:

The slashing percentage's of each cross-delegator funds can be kept on the vault, so that they can be slashed without requiring an unbonding. This is a simple solution, but it's a little undesirable, as it'll reduce the amount of funds that can be staked, either natively or cross-chain. It also does not protect against multiple slashing on different Consumer chains.

Some or all of the block rewards can be kept, to build a treasury of funds on the vault, for each validator on the Consumer, to be used in case of slashing. Again, this is undesirable, as it'll make cross staking less attractive.

Perhaps there are other solutions to this. None of these look like a good idea; listing them here for completeness / documentation. And to estimulate discussion about it.

maurolacy commented 1 year ago

Consumer chain mooning: If the Consumer chain moons (its token price increases significantly), the amount of Provider funds can be insufficient to cover slashing amounts.

Some kind of protection can be built around this: Suspending cross staking, i.e. unbonding cross-staked funds, in the case of the Provider chain mooning, so that the possibility of misbehaviour disappears. This looks like an effective solution, but will be unpopular / have undesired effects if / when triggered. Cross-staking could be resumed / re-bonded automatically as soon as the cross-delegators add the required funds under the new price, and / or the Consumer's token price goes down. This would be complicated to implement, but will turn the solution more attractive.

Alternatively, some kind of treasury can be built on the virtual staking contract (which is on the Consumer side), with some of the block rewards. So that if the Consumer chain moons, these funds will moon as well; as they are in the Consumer's token, not the Provider's one. This looks like a good idea. Adjusting the percentage of rewards to keep can turn this into an acceptable option. At the expense of the time required to build the "mooning reserve" funds.

Comments? @alpe, @jtremback, @JakeHartnell, @mpoke, @ValarDragon.

mpoke commented 1 year ago

Control channel: We can hook into the evidence module to receive a callback on the Consumer side:

https://github.com/cosmos/cosmos-sdk/blob/v0.47.4/x/evidence/abci.go#L24

We then pass the evidence as part of the mesh-security protocol / channel. Otherwise we would need deep chain integration on the Provider side. This builds upon the assumption that the control channel, that is, the Consumer implementation of mesh security, can be fully trusted. I would say, Providers should trust that, but would want to verify the evidence nevertheless.

Note that the application doesn't really get the evidence, but rather a list of Byzantine validators (with some additional metadata). The evidence is stored in the blockchain. Our approach on ICS is to have a relayer send a message that contains the evidence. Clearly, any user could do that, but relayers will automatize things.

mpoke commented 1 year ago

Evidence verification: For verifying the evidence on the Provider side, we would need the Consumer's validator set with the validator pubkeys, at the evidence height. That means / implies that we need to store or have access to the historical validator set. At least for the unbonding period, which is typically 21 days. This means either storing the validator set updates as part of the control channel protocol, which is already in planning (#88) or accessing the historical validator set or part of it on demand. If we can have a reliable way to query for the historical Consumer validator set, that would be a good option to storing the historical validator set changes, which will take significant storage, and cannot or is not easy to prune.

Validator sets can be obtained from IBC ClientUpdate messages. In the case of Comet, a client update contains a Header, which contains also the validator set. When a relayer is relaying an evidence of misbehavior on a consumer, it can also relay a client update for that particular height.

JakeHartnell commented 1 year ago

Think breaking this up a bit into two parts would be helpful:

  1. How to detect a slash
  2. What to do when there is a slash

We can start working on #2 in parallel. Made a ticket for that: https://github.com/osmosis-labs/mesh-security/issues/112