State Channels for Dummies: Part 6

Stale-State Griefing with Pisa

Eric Olszewski
BlockChannel
10 min readSep 3, 2018

--

Note: This post is greatly aided by some background knowledge of state channels. If you have not already, I advise going through the series from the beginning to provide more context for this article.

What

In state / payment channels, participants exchange messages between each other until they are ready to settle / close the channel. In the ideal case, all participants have 100% uptime and when they want to settle the channel, they:

  • Agree to the latest state
  • Deploy their off-chain contracts (if there are any)
  • Submit the latest state to these contracts
  • Wait for the challenge period to elapse (where any party can submit a later state to the contract to contest the one previously submitted)
  • If there are off-chain contracts that had been deployed, submit a conditional payment transaction to their multisignature wallet (which pays out according to some information on the newly deployed smart contracts)
  • If there were no off-chain contracts, submit the latest state to the multisignature wallet, directly.

In the case that one of these parties is offline (Bob), the other (Alice) can submit an earlier state which would resolve to a more favorable outcome for her than the latest state. Given Bob’s unavailability, Alice can submit earlier state, unchallenged, and ‘grief’ Bob. Below is an example presented in part one of this series where Alice attempts to grief Bob, but fails to do so:

Alice and Bob create an multisignature wallet and both sign payments with nonces 0 and 1
Alice attempting to submit older transaction, triggering a new challenge period
Bob submitting the newest transaction, causing Alice’s old transaction to be overwritten and triggering another challenge period
Multisignature contract paying out after challenge period expires

In this article, we will be reviewing Pisa and other strategies to account for the times where Bob is not available to contest Alice’s fraudulent transactions.

Why

Assuming that people are not always online and monitoring the channels that they have open, a strategy for mitigating any sort of griefing is highly desirable. In the above example, if Alice had succeeded in submitting an earlier state, Bob would have been cheated out of 5 ETH.

How

Everything in channels is contextual — when constructing a payment / state channel, it is crucial to understand both the duration that the channel will stay open for (deadline) as well as the process for settling / closing a channel. Without these being well understood, you leave yourself open to the possibility of having a channel which is open indefinitely or potentially a channel in which parties are unable to dispute what the other had submitted as the most recent state.

Deadline / Expiration

Different channels call for different time durations :

  • A channel containing a game of Risk that you have open with some soon-to-not-be friends, might be open for a few days.
  • A channel open with your roommates where you each pay the others back for rent, utilities, groceries, etc… might be open for months.
Destroyer of Friendships

The point of putting a deadline on a contract is to ensure that if nothing occurs within a certain of time that parties can withdraw the money that they had initially deposited. Here is an example of a simple one-way payment that allows for an expiration to be set in the constructor to ensure that the creator of the channel is able to withdraw their funds after a certain period of time (in the event that the recipient doesn’t respond / take action). If the participants of a channel agree, they should also be able to extend the deadline to better suit their needs (maybe that game of Risk is taking longer than they expected).

Dispute Resolution

Within state channels, challenge periods define an interval during which a state submitted on-chain can be disputed. Disputes are prioritized based on their sequence number / nonce — if the dispute nonce is greater than the nonce which was previously submitted, the contract state is updated and a new challenge period begins. Any dispute which is in progress should be able to be canceled with unanimous consent from the participants of the channel.

A great example of each of these pieces of functionality can be seen in Counterfactual’s StateChannel.sol.

Note: All state updates submitted to the smart contract must be signed by all participants to be considered valid (aside from on-chain state updates with a turn-based framework).

Pisa

There are a few different solutions to stale state griefing in the community, these chiefly include monitors and watchtowers. Both of these solutions have their shortcomings when it comes to storage requirements, channel-size limitations, and accountability of monitors / watchtowers. This is where an alternative solution, Pisa, comes in — Pisa’s protocol goals include the following:

  • State Privacy: only hashed state is provided to the custodian.
  • Fair Exchange: payment is always exchanged for a signed receipt.
  • Recourse as a Deterrent: receipt can punish a dishonest custodian.
  • Non-Frameability: a full collusion of all channel parties cannot attack an honest custodian.
  • Efficiency: storage requirement is O(1).
Will you solve griefing for us, leaning building?

Setup

In Pisa, a ‘customer’ hires a ‘custodian’ for an ‘appointment’. When approaching the custodian, the customer makes it known which contract needs to be watched. After analyzing the contract and understanding how to settle a dispute on it, the custodian sets up a payment channel between themselves and the customer with a large security deposit that can be used as collateral in case he / she cheats. This payment channel also details the duration and cost for each appointment.

Custodian creating a payment channel with the customer and putting down a security deposit

If the customer is satisfied with the size of the security deposit as well as the cost / duration for each appointment, they can then make a deposit into the contract that they can use to pay with a payment channel.

Customer agreeing to the terms of the payment channel and putting down a deposit to use for payments within the channel

Integration

Members of the state channel would then proceed as normal, aside from the fact that they would be passing around signed ‘blinded state’ as well as plaintext channel state. Blinded state is the state nonce as well as a hash of the state — this allows for this to be shared to other parties without divulging any state-specific information.

Note: Channel members can exchange plaintext channel state using public key cryptography, symmetric cryptography, unencrypted, etc… — this is dependent upon their messaging infrastructure.

This is what a few offchain transactions would look like with this setup:

Each participant is responsible for storing their own copy of the private state as well as the offchain transaction which contains the state nonce and hash of the state.

With Pisa, after receiving new state, a customer would forward it to the custodian through the following process:

  1. Customer sends blinded state (hashed state plus nonce)
  2. Custodian validates signatures
  3. Custodian gives a signed receipt (Appointment start / end time, signed hashed state, random hash number r)
  4. Customer returns conditional payment with random hash r based on the pre-image of r
  5. Customer waits to receive the pre-image of r (either offchain or through the custodian redeeming the conditional payment on-chain)

What this process looks like:

Customer sends the last-received state to the custodian.
Custodian includes a random hash with the receipt — for the receipt to be valid in the payment channel, it must be submitted alongside the pre-image of the random hash (only custodian knows this, presently).
Customer’s payment is only valid if submitted with the pre-image of the random hash that was included with the payment (same as the one sent to the customer with the custodian’s receipt).
Payment channel smart contract requires that pre-image is submitted as well as hash for the transaction to be valid. So, once the payment from the customer has been redeemed, the customer has the pre-image to make their receipt valid as well.

At this point in time, if an earlier state is submitted to the smart contract and the customer is successfully griefed, they are able to submit their signed receipt from the custodian (as well as the hash pre-image) to the payment channel and get paid out the entire security deposit (30 ETH).

Happy Case

In the happy case of this protocol, if the customer goes offline and the other parties attempt to grief them, the custodian will then submit the latest state to the smart contract, preventing the customer from being successfully griefed.

Griefing attempt made
Attempt thwarted by our custodian
Customer submits pre-image of blinded state to finalize channel
Challenge period ends for channel, contract pays out

Malicious Custodian

There will also be the case where a custodian could be malicious — this would happen if they were guaranteed by the other members of the state channel to gain more by colluding than the value of their security deposit. To mitigate this, it is recommended that the custodian put up a large security deposit.

Shortcomings

There are many benefits to this approach which are listed above in the protocol goals, but there are also areas where the protocol can be further improved for a more fair and robust system.

Capital Lockup

In Pisa, payments between a custodian and customer are facilitated through a payment channel. Before any payment is issued to a custodian, they must create a payment channel with a prospective customer — this prospect will then review the security deposit on the smart contract as well as the cost and duration for each appointment.

If the customer decides not to move forward with the custodian, the custodian has wasted gas on the smart contract to construct the payment channel and may have their security deposit subject to an escrow period defined by the smart contract before being able to withdraw and allocate it elsewhere. And even if the customer does decide to move forward with the custodian, they may not engage with the custodian, causing the custodian’s security deposit to again be tied up for an implementation-specific amount of time.

Large security deposits also limit the impact of custodians to just a few channels given their overcapitalization.

Collusion

Custodians should logically always act in their best financial interest. In the case where they stand to earn more from malicious activity than from being a good actor, they should behave maliciously. This leaves them open to collusion with other members of the channel where everyone except for the party being griefed benefits — leaving us at square one, really.

Payment for Inaction

In Pisa, even if there is never any griefing which occurs in a channel, the customer pays the custodian. This seems inefficient for the customer as they are burning capital for no true added benefit (the custodian could be malicious and still benefit!).

Latency Griefing

Given that Pisa depends on appointment windows where custodians are only held accountable for the time duration of the window that they signed up for, members in the channel could collude to proceed slowly so that any challenge would be outside of the appointment window.

Single Point of Failure

A number of people like to point to this model and say that it could be susceptible to a DDoS attack or that the custodian might experience some natural disaster which takes them offline for an extended period of time. The former case is very hard to justify without knowing the value stored in the state channel — if the custodian was an XXL AWS box, it would take an immense amount of capital to bring that thing down, and the effort would only slow it down, honestly. The latter is a legitimate concern, custodians could certainly set up multiple servers located around the world to mitigate this possibility.

Potential Improvements

An alternative approach that I have been working makes the tradeoff of accountability provided by the security deposit to address each of these shortcomings.

This alternative model would be one in which all blinded state is made highly available and broadcasted to a network of custodians. The reward model would also be based on the submission of a successful dispute, whereby the reward would be issued from the contract. In order to provide this reward to the contract, every dispute would have to be submitted with a required ‘dispute bond’. This would cause the griefing party to have to pay for the dispute (instead of the party being griefed) and award the disputing party (custodian) on the basis of successfully challenging a dispute.

With this network in place, the participants in a channel would have to bribe many more parties to prevent one from submitting the latest state to the smart contract. Take the following example:

  • There are 100 custodians in the network.
  • The channel has a dispute bond of 0.5 ETH + gas costs
  • Channel participants have 28 ETH that they gain from successfully griefing one party.

In order to prevent one of the custodians from successfully disputing, the participants would need to offer all of them something greater than 0.5 ETH. Given that they only have 28 ETH to work with, the max they could offer is 0.28 ETH (which would leave them with no benefit for having griefed one party in the first place). Given that custodians should act in their best financial interest, this makes it impossible for channel participants to collude with the network.

Who is Working on This?

I am not sure who is currently working on an implementation or if this is still in the research phase, but I have linked to a presentation on Pisa given by Surya as well as the whitepaper, below.

Further Reading

I highly encourage everyone to check out Surya Bakshi’s presentation from Binary District’s Master Workshop and to read their whitepaper.

Interested in Being Featured?

If you have any interesting projects that the community would benefit from leveraging / understanding, I would love to see your implementation and how you’re approaching things.

Feedback

If there’s something about this that I can improve, please don’t hesitate to let me know in the comments section, below. And if you’ve gained something from this article, please spam the clap button and share it (these simple actions really make a huge difference). Here’s the link to do so:

https://medium.com/@eolszewski/state-channels-for-dummies-part-6-7aae9c08ddee

Find me on Twitter or Github!

--

--