consensus-shipyard / ipc-actors

Rust implementation of the IPC actors for FVM
MIT License
6 stars 3 forks source link

Staking with reusable delegation #27

Open aakoshh opened 1 year ago

aakoshh commented 1 year ago

(Needs a better title. This is similar to what was originally proposed as "merged staking" according to @adlrocha; see below)

Summary

I'm proposing that we change the design of subnet security by allowing users to delegate the same tokens to validators in multiple subnets, so that we can counter some of the inherent vulnerabilities in the current design.

Background

The current design of the collateralisation of subnets is relatively simple: users on the parent subnet can use the join and add collateral operations to become validators on a child subnet, locking up their tokens in the contract. Notably, this operation does not affect the circulating supply on the subnet, the tokens stay in the parent subnet; they only serve as collateral and drive the voting power (depending on the subnet implementation), so they are orthogonal to the firewall property.

This model is more or less equivalent to the V2 version of InterChain Security of Cosmos. To summarise the different versions of ICS, the way I understand them, with some nomenclature changes (provider chain becomes parent subnet, consumer chain becomes child subnet):

Note on ICS delegation

Actually under Chain-Specific Delegations of ICS they mention "This would allow a delegator to delegate ATOMs to a [...] validator on the Hub while also delegating the same ATOMs to a [...] validator for a Consumer Chain at the same time", as a potential future development. That is very similar to what I'm proposing here. In their initial design, however, delegators delegate to validators in the provider chain once, and the validator decides whether to join a consumer chain or not.

Subset problem

The designers of ICS recently announced they are abandoning their plans for V2 and V3 because of the subset problem, which makes them inherently insecure. They will keep V1 because it maintains the full security of the parent subnet in each child subnet.

The subset problem is simple: by fragmenting the stake across multiple subnets, we have to abandon the assumption that any of these subsets of delegators/validators hold the BFT security requirement of being +2/3 majority honest. In other words, a subnet with lower amount of stake behind it is easier for the adversary to take over, and by spreading the collateral thin, we create opportunities for them.

What is particularly worrying is that it's difficult for users to put their trust into a subnet with relatively low amount of collateral, because the adversary can always potentially bring in more. They don't have to acquire tokens in the subnet, pushing up the price, or buying it from people unwilling to sell it to them. They can get it on the more liquid parent subnet, ie. get more FIL; they might already have it, who knows. This makes it very difficult to reason about the security of a subnet below certain size.

Once the adversary has taken over, they can do anything, for example steal all the funds in the child subnet and credit it to themselves in the parent subnet, by creating fraudulent checkpoints.

Of course, this is nothing we didn't know before. Our arguments regarding the matter were:

With the obvious parallels between our design and the discarded V2 version of ICS, it would be good to revisit this issue and if possible find some remedies, because the question of why we're sticking to our guns will no doubt arise.

Proposal

My proposal is changing the staking/security design of Inter Planetary Consensus to have a two step mechanism:

  1. Users lock up their tokens in the parent subnet for staking
  2. Users choose how much of their locked up stake they delegate to individual validators on a per subnet basis, without exceeding their locked stake in any given subnet, but allowing the tokens to be allocated to multiple subnets at the same time.

At the extreme where every delegator delegates all their tokens to every subnet in equal measure, this would result in each child subnet being equally secure and equally costly for the adversary to attack. Not as costly as the parent subnet, because the parent subnet is secured by its own parent. But it can avoid the dilution and fragmentation of security between child subnets.

Delegators essentially create multiple liabilities against their common locked stake to accept damage for slashing, in exchange for rewards from the subnet they delegate to. Notably, they do not create new tokens, because the delegations do not increase the circulating supply of the child subnet. It's purely a game of risk and reward.

The scheme has the potential to bring security similar to V1, while being as flexible and scalable as V2 of ICS. Delegators pick validators and the subnet code they can trust.

Mechanism

A rough pseudo code of what a potential implementation could look like can be found here.

There are two mappings in the parent subnet:

The rules are:

Pros and cons

Naturally, the proposal is not a silver bullet, in fact it seems controversial. We should use the opportunity to analyse it and decide if it's viable.

Pros

Cons

Looking at the cons, it's easy to see why the V1 version is an appealing default: the system is most secure when every delegator delegates to every subnet. But in our case we want subnets to be very different from each other, with their custom consensus mechanisms and custom implementations; it would be unreasonable to require every delegator to risk their tokens on any subnet, and it would also be counter productive to require that subnets can only be created if the majority agrees to it. The proposal allows security to be brought in where there is value and trust, but it's up to the delegators to do so.

Example

Say that we have Filecoin as the rootnet where FIL is mined, and there is a set of people with a total amount of C tokens they are interested in putting up as collateral in exchange for R amount of rewards. For the sake of example, let's assume they create a subnet S and put all collateral C behind it, getting R in fees for running a BFT consensus.

After some time, two dominant applications emerge, A and B, with the ratio of revenue generated by them being 8:2. Say there is a decision to split S into Sa and Sb (as subnets of the rootnet) to run A and B, respectively.

The question is, how much collateral to put behind each subnet.

(See an illustrative spreadsheet below).

Without reuse

Delegators are used to a return of R/C. Sa generates 0.8*R revenue and Sb does 0.2*R (this is probably not true in real life: fees would presumably be lower because there is less contention, but traffic might be higher as the applications run smoother, and the operations cost might be less because there is less for individual validators to validate).

Naturally, by allocating 80% of C to Sa and 20% to Sb, the returns are kept as they were at R/C. By contrast, a 50:50 distribution would mean on Sb we get (0.2*R)/(0.5*C) = 0.4 * R/C.

So, we have 0.8*C backing Sa and 0.2*C backing Sb. This is where the subset problem comes in. Previously we assumed that S was secure as long as +2/3 of C was backing honest validators. In other words, we could tolerate up to, say, 0.32 * C being dishonest. What happens now that we split the subnets?

Just under 1/3 dishonest stake would allow two attacks to happen:

Dynamic rebalancing

Perhaps another, less intuitive strategy is if every honest delegator delegates their stake in the proportion of existing total delegations to the subnets, dynamically rebalancing to keep their allocation in line as the totals change over time.

The idea is that if 0.68 of C is honest, then as long as the same ratio is kept at all times in Sa and Sb, everything should be fine. This can be achieved if a delegator with collateral c, taking up a fraction of c/C of all stakes, takes up c/C of the collateral of both Sa and Sb. For example if the current allocation of collateral between Sa and Sb is 10:90, then delegators would put 10% of their stake behind Sa and 90% behind Sb. If every honest delegator follows this strategy continuously, that should result in them always controlling 68% of the collateral in any subnet.

This strategy would mean that the profitability of subnets would vary wildly: the ones with more collateral would have lower return; but this would be compensated by the less collateralised ones having much higher yield, ultimately balancing it out for anyone who allocated their stake to all subnets. For example the delegator who owns c/C of the stake earned R * c/C from S, and now does the same, because they still own c/C of the revenue from each individual subnet.

It's probably not realistic to expect that delegators should not try to put more stake behind more profitable subnets, though. And it's also scary to think that this strategy could leave some subnets with almost no collateral, e.g. if the adversary puts 99% of their collateral behind Sa, everyone else would have to do so as well, leaving Sb seemingly undefended, and free to be taken over by unallocated or new collateral.

With reuse

If we allow delegators to use the total amount of C to back Sa and Sb at the same time, then if they do in equal measure, everything stays as it was:

Looking at it in a different way, of course this is what we want: originally we had A and B running on the same subnet S, secured by C. By moving them to separate subnets Sa and Sb, all we did was choose a different deployment strategy. The amount of value locked inside the applications did not change. Why should we be forced to accept less security as a consequence?

Conclusion

The above proposal is an attempt to get out of the corner where the subset problem puts us. It might not appeal to everyone, some might want to have stake exclusively dedicated to their subnet, or maybe it just offers too dangerous trade-offs. Depending on how subnet actors are coded, this kind of security can be entirely optional, with some subnets supporting it while others not. In any case, I'm really curious what people think.

aakoshh commented 1 year ago

The difference between "merged staking" presented in Proof-of-Stake Sidechains and the proposal here is as follows.

Trying to project merged staking to our hierarchical construction, we would have the parent subnet P (mainchain) and the child subnet (sidechain) C, where P has tokens Tp and C has tokens Tc. The voting power in P would come from Tp, and the voting power in C would come from Tc and Tp (from the validators that declared support for C). It is very similar to V3 of ICS.

Our case is different, because in IPC, the tokens Tp do not participate in securing P (and similarly Tc does not secure C); for us, a subset of Tp directly secure C. (The rootnet does not use PoS, so there is no case where the token would have to secure both).

So the motif of reuse is present in both, because with merged staking the same Tp used to secure P can be used to secure any number of side chains (at least that's my interpretation). But while with merged staking it's the validator that decides which sidechains to participate in, the current proposal would allow the delegators to make their choices on a per-chain basis, supporting one validator here and another there at the same time with the same token.

Note that merged staking also suffers from the subset problem, because only validators who signalled their awareness of (ie. opted into) a sidechain will participate in block production.

adlrocha commented 1 year ago

Thank you for the proposal @aakoshh. It would be great if we can come up with an objective security metric and high-level framework to test the different approaches. I like the idea of allowing plain users to stake some of their tokens that they can delegate to validators in a specific subnet. What I am having a harder time to wrap my head around is the fact that staked tokens can be used in parallel to delegate power to validators in more than one subnet.

Each subnet is completely independent of its syblings so, intuitively, as long as the parent is secure it should be fine to delegate the same tokens in more than one subnet. However, where I feel the model may break is on the type of attacks we may introduce by sharing tokens between different networks. For instance, an idea from the top of my mind, what if an attacker behaves as an honest validator in a subnet in order to accumulate as much power from users protecting other subnets, and after a while the attacker misbehaves on purpose in order to slash the stake of the users protecting other subnets allowing them to mount a cheaper attack in these networks? These are the kind of rough edges I would like to uncover with the analysis, but definitely something worth spending a few cycles in.

aakoshh commented 1 year ago

Thanks for positing that attack @adlrocha; it's different from the ones I listed in the cons, somewhat similar to the 3rd.

I think these issues should be mitigated in practice by measures such as:

ranchalp commented 1 year ago

Very interesting. There is definitely a challenge in ensuring the adversarial delegators cannot decrease security in otherwise robust subnets by propagating slashed stake in another subnet, as pointed in the cons. If upon evaluation this proves to a blocking factor compared to the current approach of "one stake one subnet", it can be worth exploring limiting to which subnets can delegators simultaneously delegate.

For example, if each subnet is a country and adding collateral is pledging part of that country's army (to continue with our analogy in our previous chat), it seems reasonable that the group of countries belonging to NATO allow a union member to simultaneously pledge their army to any of the at the same time in the event of an armed conflict, but only if they do not pledge this same portion with anyone outside of NATO too (i.e. NATO members would not be happy if their pledged reserves decrease because of a conflict external to NATO that NATO was not even aware a union member was involved in). This can greatly limit the potential dangers of the adversary if subnets select proper subnets to whitelist/blacklist for "merged stake". This way, the security of a subnet goes back to being explicitly stated by the validators/governance of that subnet, instead of depending on where the delegators decide to stake.

aakoshh commented 1 year ago

@ranchalp thank you for commenting.

To harp yet more on the NATO analogy: I think the existing proposal for V2 of ICS was that instead of countries delegating soldiers to NATO, they delegate it to commanders (validators) and then the commander decides if they want to defend a country in trouble or not. That is, the power of the validator was given once in the hub, usable anywhere, and multiple times as well, because the same validator can be slashed in any consumer chain, and be punished in the hub.

Reusability would allow a country to delegate to local commanders on a country-by-country basis, with the caveat that the soldiers might have perished defending another territory when you need them.

Your concern is that at least that other territory should be a NATO country too. I think that in our IPC construction that is naturally the case. Say we have the following subnets:

    root
   /    \
  A      B
 / \ 
1   2
|
x

In /root/A, users can only use for staking the tokens they have moved into /root/A, and they can only use it to secure /root/A/1 or /root/A/2; they cannot use them to secure /root/A itself, nor is staking transitive, ie. they aren't contributing directly to the security of /root/A/1/x. I am proposing that they should simultaneously be allowed to secure /root/A/2 with the same tokens.

If we consider /root/A to be NATO, and its immediate subnets the comprising countries, then you can see it's impossible to commit the tokens within it to any other country outside the alliance.

To be fair this is a very rigid alliance system, it doesn't cater for matrix structures. And you're right, if someone creates another set of subnets within /root/A which you think are an anathema to 1 and 2 then there might have to be more complicated rules to disallow reuse between them.

aakoshh commented 1 year ago

Here's a spreadsheet demonstrating the effect of a variant of the model where the delegator tokens would be locked up in the rootnet, and allocated from there directly to any subnet/validator combination, with reuse, so that there is no fragmentation of the potential collateral:

https://docs.google.com/spreadsheets/d/1liRUo6KMtZ-nwG1rQv2K-0LLePFJlIzwJsEej7QmzoY/edit?usp=sharing

It is contrasted with the default model where validators themselves move their collateral to the subnet where they want to participate, without the ability to reuse.

aakoshh commented 1 year ago

Similar idea taken to product level: https://www.eigenlayer.xyz/