Skip to content

Instantly share code, notes, and snippets.

@christophersanborn
Last active June 4, 2019 16:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save christophersanborn/035e3110aff520ddfa8906484db86ddf to your computer and use it in GitHub Desktop.
Save christophersanborn/035e3110aff520ddfa8906484db86ddf to your computer and use it in GitHub Desktop.
Short-lived Unidirectional Payment Channels for BitShares
BSIP: <BSIP number>
Title: Short-lived Unidirectional Payment Channels for BitShares
Authors: Christopher J. Sanborn, ...
Status: Draft
Type: Informational
Created: 2019-06-04
Discussion: <url>

Abstract

We describe a methodology for implementing short-lived one-way payment channels on top of the BitShares protocol. The proposed methodology requires only a very slight modification to the existing BitShares core protocol, described in a separate BSIP.(*) The maximum lifetime of the channel is constrained by the committee parameter maximum_time_until_expiration (currently set to 1 day). However, we note that there are use cases wherein this constraint is not limiting. In particular, these channels may be used to implement ILP-style streaming micropayments, while keeping on-chain transactions to a minimum.

(*) The needed protocol change is the addition of a predicate to the assert_operation which tests that a certain head block time has been reached. This predicate can be used to enforce a time-lock on channel-escrowed funds.

Motivation

Comparatively speaking, BitShares is a “fast” blockchain, with transaction block inclusion typically happening within about three seconds, and finality within approximately a minute. Because of this performance, it may seem that “payment channels” are an unnecessary construction on BitShares: transfer operations are both cheap and fast.

However, the Interledger protocol (ILP) provides one interesting use case in which payment channels would be a significant benefit: streaming micropayments. ILP transfers route payments across a network of connectors which may span disparate ledgers, and ensuring transactions are atomic can be challenging or impossible in some cases. In these cases ILP can implement a different security model based on limiting exposure rather than ensuring atomicity. In this case, ILP will “stream” a payment as a series of micropayments negotiated via ILP “packets”. A successful packet implies a transfer of a debt claim for a tiny amount. When an individual connector on the network has extended credit to a downstream connector beyond a tolerable threshold, they may require “settlement” on the relevant ledger before routing further packets. This is repeated until a payment is complete, and at no point along the way has any connector extended credit beyond their own tolerable risk thresholds (which may be very small.)

Thus you can imagine that a $100.00 payment across ILP may be routed via 10,000 ILP packets for $0.01 each, with “settlement” being required every $0.10, perhaps, for a total of 1,000 settlement operations. If each of these settlement operations required an on-chain transaction, the fees (and chain storage requirements) would be unnecessarily large, even for a fast, inexpensive chain like BitShares.

Thus we seek a payment channel construct in which we may open a channel in a single on-chain transaction, negotiate state in a side band, then close the channel in a second on-chain transaction for a total of only two transactions. Clearly, this is a big savings over 10,000 individual transactions.

Rational

Why Short-Lived Channels?

  • Long-lived channels would require a BitShares protocol upgrade.
  • Because BitShares is a lightweight and fast chain, channels can be open and closed quickly and cheaply, and do not need to persist. Compare with Bitcoin where opening a channel is (or in the future may be) expensive, and so the user is incentivized to keep long-lived channels. In BitShares, a channel may be opened for a single purpose, utilized, and closed quickly. Case in point: an ILP transaction, which may be composed of thousands or even millions of packets, will generally complete in a matter of seconds. A payment can open, use, and close a single-purpose channel. A subsequent payment can use another one.

Why Unidirectional Channels?

  • Simplicity. No analog to “check sequence verify” is needed. Receiving party is naturally incentivised against broadcasting an earlier state. Sending party has no ability to do so until after a time lock.
  • Because these are intended as light-weight and temporary channels, bidirectionality isn’t really needed. If at some point funds need to flow in the other direction, that can just be done in a separate channel.

Specifications

Opening and Funding a Channel:

One-time setup:

  • Sender Alice registers an account to serve as the channel. This will allow for multisignature authorities to be constructed. (Account registration only needs to happen once, and multiple channels may be opened and closed via the same account. The account is just needed to provide a vessel for multisig authorities.)
    • Created Account: alice-to-bob-pc
    • Initial Authority: [[‘alice’, 1], thresh: 1]
    • Initial Balance: 0

Per-channel setup:

  • Sender wishes to initialize a channel to Bob and fund with 100 bitUSD. Sender asks Bob for a unique public key under Bob’s control to use in channel authority.
  • Sender constructs an unsigned (and as-yet invalid) transaction with the following operations. This will be Alice's "Time-Locked Refund Transaction" and allows her to recover channel funds if Bob fails to close the channel.
Operation Details
Assert: block_time > (now) + (channel lifetime)
Transfer: 100 bitUSD from alice-to-bob-pc to alice
Update Authority: Revert to: [[‘alice’, 1] 1]
  • Sender then asks Bob for a signature on that transaction. Bob delivers over private communication channel.
  • Alice is now safe to fund the channel. So she broadcasts a transaction with the following operations:
Operation Details
Transfer: "enough" BTS from alice to alice-to-bob-pc to cover anticipated fees.
Transfer: 100 bitUSD from alice to alice-to-bob-pc
Update Authority: [[alice-pubkey, 1], [bob-pubkey, 1], thresh: 2]
  • Account alice-to-bob-pc can now ONLY be used by Alice and Bob together in agreement, but Alice has a bailout in the form of a time-locked signed refund transaction. The bailout will refund Alice AND restore account control to her.
  • Bob sees that an account now exists on chain for which he has 50% signing authority. This will serve as a payment channel in which funds can flow from alice to bob.

Notes:

  • Timelock: The timelock for the refund operation is enforced by the assert operation. It is important that this is beyond the desired lifetime of the channel (to give Bob time to cash out on the final channel state) but not so far in the future as to overrun the limit on the TaPoS parameters or maximum_time_to_expiration, so as to give Alice a time window in which to close out if Bob disappears.

Updating State:

Updating state is a matter of the sending party sending signed transactions apportioning the channel balance incrementally in greater favor of the receiving party.

Initial state:

  • Alice has: Time-locked refund operation
  • Bob has: (Nothing)

Alice sends bob $1.00:

  • Alice has: Time-locked refund operation
  • Alice gives Bob a half-signed Tx with the following operations:
Operation Details
Transfer: 99 bitUSD from alice-to-bob-pc to alice
Transfer: 1 bitUSD from alice-to-bob-pc to bob
Update Authority: Revert to [[‘alice’, 1] 1]

Alice sends bob another $1.00:

  • Alice has: Time-locked refund operation
  • Alice gives Bob a half-signed Tx with the following operations:
Operation Details
Transfer: 98 bitUSD from alice-to-bob-pc to alice
Transfer: 2 bitUSD from alice-to-bob-pc to bob
Update Authority: Revert to [[‘alice’, 1] 1]

After two state updates, Alice still has her refund transaction, which she can only use AFTER channel expiry. And Bob has two state-update transactions with Alice’s signature on them, to which he may apply his own signature and broadcast at a time of his choosing. At any time prior to channel expiry, Bob is the ONLY one who can broadcast (because Alice’s refund is time-locked by the Assert operation.) After channel expiry, Bob may still broadcast but is in a race with Alice.

Because the channel is unidirectional, Bob is naturally incentivised to sign and broadcast only the LATEST channel state when Bob is ready to close the channel. No “check sequence” validation is needed to prevent an earlier state from broadcasting — it is Bob who loses out if he neglects to broadcast the latest state.

Rebalancing a Channel:

To “rebalance” a channel (e.g., the sending party wishes to add more funds to the channel in order to continue sending to Bob after the channel has run dry), it is necessary to invalidate previously signed refund and state-update transactions. This can be achieve by updating the account authorities of alice-to-bob-pc to a NEW pair of public keys supplied by Alice and Bob.

(Details to be written, but: Basically Bob needs to provide Alice a new signed, time-locked refund operation, signed with Bob’s NEW key. Alice provides Bob a new state-update transaction signed with HER new key. Alice and Bob then mutually sign a transaction that simultaneously updates channel authorities and also includes a transfer from alice to alice-to-bob-pc that provides the additional funds. It may optionally also include a cash-out transfer from alice-to-bob-pc to bob for the amount already transfered, but this extra transfer op would imply an extra fee, so Bob may prefer to leave the balance in the channel. Because Alice and Bob have already exchanged new refund and state transactions based on the new keys, Alice and Bob are now mutually safe to sign a Tx updating the authorities. Bob, obviously, will not sign unless this Tx adequately funds the channel as per the agreed rebalancing.)

This operation also has the side effect of extending the lifetime of the payment channel, since the newly negotiated refund and state-update transactions can reference more recent TaPoS parameters.

Extending a Channel:

Extending the deadline/expiry of a channel is the same as the process of rebalancing, except absent the addition of new funds.

Closing a Channel (Receiving Party):

The receiving party (Bob) is responsible to close the channel prior to channel expiry, else he will find himself in a race against Alice’s time-locked refund transaction.

Closing the channel is simply a matter of signing and broadcasting the latest “state update” transactions that Bob has received from Alice.

Upon closing the channel, the funds held in the multisignature account alice-to-bob-pc will have been disbursed, and the account authorities will have been reverted to giving Alice sole control of the account. (She may then reuse the account for future payment channels.)

Closing a Channel (Sending Party):

If the receiving party neglects to close the channel prior to channel expiry, the sending party (Alice) may sign and broadcast her refund transaction, which is only valid after channel expiry. Alice is responsible to broadcast this transaction prior to the platform imposed limits of TaPoS parameters and maximum_time_until_expiration or else the transaction will become invalid. (Should this happen, she may informally, of course, negotiate with Bob (who also failed to meet an obligation) to sign a mutually agreeable transaction to close out the channel.)

Discussion

Risks to channel operators

Chain halts or other system-wide extended outages

In the event of a system-wide chain halt, there is a risk that channel state-update and refund transactions will expire before the chain resumes, essentially erasing channel state. In this case, funds will be locked in escrow in the payment-channel account. Because Alice and Bob are both signers on that account, they can, in principal, negotiate a settlemnt transaction to disbures the funds as intended. But they run the risk of deadlock if they cannot come to an agreeable course of action.

Changes to fees and parameters

Since BitShares uses explicit fees in the transactions, the half-signed time-locked refund transactions and half-signed state-update transactions will have fees explicitly referenced that were valid at the time of initial signing. If the fee schedule is updated while a channel is open, these signed transactions may become invalid.

Similarly, if the committee parameter maximum_time_until_expiration is updated, it may disrupt open channels, particularly if the parameter is shortened. (Lengthening the parameter, however, would likely be harmless.)

Summary for Shareholders

Copyright

See Also

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment