And wearing the hat of promoter for generalized state channels, pay-per-hop can also be viewed as “pre-compiled” SLA resolution, where per payment fee is depending on the SLA of “deliver my payment to destination”.
Can you give an example of a simple SLA proof construction that works? I’m struggling to see how whether an off-chain SLA has been met falls into the class of things that the chain can adjudicate. For example, the following things look the same to the chain:
- A promised B to route up to 5ETH a day. A claims that they met the SLA, as B sent them one request to route 2ETH, which they routed to C for them.
- A promised B to route up to 5ETH a day. B claims that they missed the SLA, as B sent them two requests to route 2ETH, and they only routed one of them to C.
Is it possible to distinguish between these two cases on-chain? It seems like you’d at least need to introduce a trusted third party here (in which case it can’t be done trustlessly), and even then it’s difficult to see how to judge whether someone actually received something that they’re claiming they didn’t (when, for example, you allow messages to be dropped by the network so that “proof of send” != “proof of receipt”).
On reflection of my above answer, I believe I made an mistake implying there are various simple SLAs can be enforced in a state channel network scenario. The only simple SLA that is on-chain verifiable is one’s service provider’s total deposit and deposit time length to him/herself and that is trivial to verify. This SLA is simple to verify because the state is local between involved counterparties. In that model, subscription can be done and it is just like today’s Internet ISP’s SLA to end users: “down load speed up to 100Mbps”. If people feels like their ISP is not living up to that promise, they will just pay up this month’s subscription fee and switch to a different provider next month.
“Guaranteed delivery” is a indeed a more complicated SLA to verify. Before going into trust/trustless constructs, I would like to highlight that this is hard because the state being disputed involves parties external to the channel being disputed. However, I am inclined to think that it is still possible with more intricacies. Thinking out loud here and let’s discuss and see if the following construct works.
Let’s assume the simple topology A – B – C. Let’s also assume the SLA between A and B is specified as “able to deliver all available deposits to destinations”. Note that this SLA needs to be mutual in nature: for A -> B direction, destination can be a very wide range or simply *, but for B->A direction, the destination is just A. Similar arrangement exists between B and C. Let’s assume A is trying to transfer money to C. A will only qualify to complain about the SLA by claiming (may not be true) an HTL transfer that is destined to C is not reaching C. He will file that complaint by submitting a pending HTL transfer (however one constructs it, can be specialized object but we are doing it as a generalized conditional state transition object) to the instantiated SLA judgement contract.
Upon this challenge, if B seriously cannot deliver this payment to C (e.g. due to depleted channel balance), then B will just swallow this and accept the failure of SLA.
However, if B believe that A is being unreasonable, he can pick up that HTL transfer, deliver it to C, get C’s signed ACK and use that as a counter-proof for this dispute. A and B will hopefully figure out if there is network outage problem or not. Note that in this A<->B only case, the common griefing scenario for state channel exists: after this back-and-forth dispute bystanders/blockchain is not able to distinguish whether A is being unreasonable or B is being deliberately unresponsive until A complains on-chain. However, this is reduces to a general challenge-response problem that every state channel will face and a common specification is defined to handle this.
Now onto the interesting stuff: the involvement of external parties. Let’s say B got the HTL transfer, it also has enough capacity to deliver it to C and he tried to send that to C, but C is just not responsive (offline or colluding with A trying to indict B on SLA). The mutual SLA comes in here. B here will claim that C is violating the SLA on the direction of B->C by submitting the HTL transfer it was trying to relay to C to the SLA contract between B and C. If C is indeed unresponsive, B, like relaying payment, effectively relays “SLA violation claims” from A to C. C will pay B certain penalty for not honoring the SLA and B will pay A SLA penalty. In this chained construct, the one who is faulty finally pays. How the penalties are constructed exactly I haven’t thought through, but this is the gist of the idea. This can also be extended to the case of multiple hops between source and destination.
Of course, I might have missed something here, happy to discuss more.
Ok, that makes sense to me. At a high level, it seems that instead of providing a proof that the off-chain SLA wasn’t met (which does seem impossible - as you put it, due to the common griefing scenario), you’re providing a challenge to meet the SLA then and there. It’s then the response (or lack of response) to this challenge, that the chain can adjudicate on.
yes sir and one particular interesting thing is the dependency on external factors here in a networked state channel scenario.
We’re also working on an implementation. Code can be found in the virtual-channel repos at https://github.com/ConnextProject. @Perun, we’d love to get your feedback as we build this out, what’s the best way to contact you?
We’re hoping to have a testnet implementation that covers the “happy” case and most dispute cases by the end of next week at the latest!
A challenge applying channels in real life is that you need to split your money into multiple deposits - in real-life situations when you do micropayments you want to have a single deposit and pay out of this deposit to everyone.
From this perspective it looks to me that things like Plasma are have advantages since with Plasma you deposit once and pay everyone …
Lightning has a similar problem that you need a separate deposit for every Lightning link which leads to lots of centralization in LN - people simply make a single deposit connect to one of handful of LN hubs …
May be I am wrong and you dont have to split deposits here but it seems from reading the paper that you do …
We built a client package that integrates at the wallet/frontend level. The package abstracts away the difficulties of interacting with the contract, generating signatures and handling dispute cases. Code can be found here (we’ll put it on NPM this week under “connext”).
We also built out an Ingrid server. Eventually, we’ll allow projects to spin up Ingrids as AWS instances through a dashboard. For now, you can do so with the code in this repo.
To save time, we decided to pass messages through HTTP for now. This is done posting and retrieving from a “watcher” server. The watcher stores state for the client as a backup, though our client package also generates a state tree which can be saved to local storage. The watcher also submits signed state in the event of a dispute if it happens to have a state update that has a higher nonce (this is done in case one of the counterparties is not available during the dispute period). We’re planning to move to WebRTC or some other synchronous communication layer soon, after which we can allow anyone to be a watcher to resolve disputes for a bounty. Code is here.
The big points of friction are the validity timer (which is not conducive to many use cases) and the inability to “fast close” a virtual channel. We think there’s ways to improve on the Perun spec using a root hash that contains a running list of open VC IDs. We’re collaborating with Spankchain on figuring this out. We’re also expecting doing a prod release of the state channel hub with them in 1 month.
Great, thanks for the update! If there are technical research challenges, we’d also be happy to discuss.