Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Fast finalization layer #29
Fast finality is extremely useful for exchanges and payment networks. We don't want users to have to wait more than a few seconds for their transaction to clear. This is especially important in the context of in-store purchases (is "buying coffee with crypto" overused?). We'd like to see if it's possible to provide real or cryptoeconomic finality for Plasma transactions.
Fast finality is important, especially in the context of payments or exchanges. There hasn't been a significant amount of research into fast finality on Plasma. Currently, users need to wait until root chain finality before blocks on the child chain are considered valid. This waiting period can be quite large (6 blocks = ~1m30s at an absolute minimum, typically).
Long waiting periods aren't great for payments. The 5s credit card wait period is probably the maximum we're willing to accept. No one wants to wait a minute and a half just to find out if their payment went through or not. This is motivation to develop a scheme for fast finality.
Unfortunately, fast finality in a real sense is probably not possible without payment channels. We might see the development of something like the lightning network on top of Plasma, but it could be useful to develop some idea of native fast finality. Let's go through some of attempts on fast finality to explore the various issues.
Shorter Block Times
Shorter block times seem like a natural way to reach faster finality. If we can reduce Plasma block times to ~5s and ensure that most transactions on the network can be cleared within a single block, then we're in business. Assuming VISA throughput of ~25,000 TPS (yes, this is played out), then we can basically hit this rate with 2^16 (= 65536) tx blocks.
Note that this would mean multiple child chain blocks within a single parent block. The main problem is equivocation by the operator - the operator might say that block N is X, but then might publish Y to the root chain. We can't stop an operator from signing two blocks at the same height, but we can severely punish this behavior. The most effective way to accomplish this is by having the operator put up a massive bond.
At this point it's probably worth considering the attack vectors here. The severity of available attacks will determine how much we have to punish the operator. In the context of a payments chain, we're most likely thinking about very many small-value payments between consumers and merchants. A payments chain might contain significant value, but realistically most users won't hold thousands of dollars on Plasma. Therefore, it's unlikely that an operator will directly gain a lot by equivocating. This isn't an ideal assumption, but it's probably good enough for most purposes.
The bigger problem in payment chains is that the operator can reverse lots of transactions. They might not gain anything directly, but they'll definitely cause harm to many end users. Therefore we need to make the cost of attack high enough that the "madman" attack isn't worth it. Ballpark, if we're transacting ~150,000 USD of value per second, then it's probably good enough to have the operator put up a 100-200m USD bond. This will almost definitely cover the value being transacted between any finality period on the root chain, plus some additional value on top to deter madman attacks. We're still vulnerable if transaction value suddenly shoots up to more than 50% of the bond.
Note: The operator needs to bond up 2x the transaction value. Operator can make a purchase for $$ => seller sends item worth $$ => operator reverses transaction => operator has $$ AND item worth $$ (= 2x $$). Seller punishes => operator loses 2x $$ => operator has nothing.
100-200m USD is still an absolutely massive bond. The operator doesn't even get anything in return for it! It's also useful to note that not everyone needs fast finality - a user sending money to their family is probably okay with waiting a few minutes. This is where finality contracts come into play. In a nutshell, the operator tells a user that their transaction will be included within X blocks or the user can "force" the operator to send the recipient funds.
The general idea here is that the operator sells "finality bandwidth". Users can buy this bandwidth to ensure that their transactions finalize instantly or merchants can buy this bandwidth for their users to use. Users can only make purchases of less value than the bandwidth. If the operator fails to include the transaction, then the bandwidth will be used to pay out the recipient.
My guess is that this will be mostly purchased by merchants to give their users "free" transactions that finalize instantly in exchange for some maintenance fee paid by the merchant.
The cool thing about this construction is that the recipient will always get the money. So this isn't real finality, but it is cryptoeconomic finality. We're usually assuming that the recipient is some sort of merchant, so it seems realistic to want the customer to experience instant finality and the merchant to have to deal with any difficulties. Merchant software will develop to handle these situations automatically.
There's an alternative to this solution where users or merchants actually purchase specific transaction slots in advance, but I think bandwidth is more general and usable.
There's another (similar) alternative to finality bandwidth where we use payment channels. Instead of allowing users or merchants to buy bandwidth, we instead allow merchants to pay for payment channels with the operator. The operator agrees to lock up some funds in the channel in exchange for a maintenance fee.
When users want to pay the merchant, they sign a special type of transaction that's contingent on the successful completion of a payment from the operator to the merchant on a payment channel. The idea here is to shift responsibility to the operator, but it also requires cooperation from the operator to actually complete the payment channel payment on time.
I think finality bandwidth is the way to go. It's the best of both worlds in terms of finality and generality, and it can be purchased by anyone on the network. We need to come up with a good way to construct the purchasing of bandwidth - my best solution here is a Plasma Cash chain where each "token" represents some amount of bandwidth.
This is amazing!
btw like to discuss about this
Isn't 1x enough? After punish, Seller got the $$ and operator has the $$ value's item, which is still a fair trade. Of course it should be 1x$$ + BIG_ENOUGH_CONST to pay for other cost and prevent operator from doing this.
One more thing I'd like to discuss about, if I have the right understanding, a coin probably could not have continuous fast finality within a root chain block time. Is this correct? In other words, if a coin is supposed to be used in root chain block N, next child chain tx of that coin should at least wait for the merkle root pushed into block N of root chain. If we have two txs within block N, second tx has no root chain merkle proof to rely on, isn't it? This might be one unfortunate limit, but we can still have fast finality in most of daily life use case if your proposal works!
One last question here which I've been wondering for a long time. For these kind of fast tx designs, how do you handle root chain re-org/fork issue? Unless you wait for enough root chain confirmation, there is always chance that this would happen. Should operator just take the risk of this? or is there a crypto-economic way to handle this as well?
This works if the seller receives the $$ as part of the punishment. Without some sort of bandwidth-like scheme where the seller is guaranteed to get the $$, the only punishment is that the operator has $$ burned. That isn't ideal, so I think bandwidth is the way to go (only need 1x + const).
Yes. I'm thinking about this in the context of Plasma MVP, but generally this is true. In the bandwidth scheme, the receiver must wait for the transaction to be included (or not) to be able to spend (or punish). So it's not "true" finality, but we're assuming the merchant is fine with dealing with this.
Not an issue in the bandwidth/finality contract design. The operator agrees to submit the transaction within X child chain blocks. If there's a re-org, then operator just needs to resubmit the block.
Now that you say it, it's probably necessary to require the operator to submit some block within Y root chain blocks, otherwise the operator can just not submit any blocks and it can't be challenged. This opens the operator up to censorship on the root chain, but we're assuming this is relatively unlikely. There's probably a way to counter this with submarine commitments and whatnot.