bitshares / bsips

BitShares Improvement Proposals and Protocols. These technical documents describe the process of updating and improving the BitShares blockchain and technical ecosystem.
https://bitshares.github.io
63 stars 86 forks source link

BSIP63: Short-lived Unidirectional Payment Channels #172

Closed christophersanborn closed 4 years ago

christophersanborn commented 5 years ago
BSIP: 0063
Title: Short-lived Unidirectional Payment Channels
Authors: Christopher J. Sanborn, ...
Status: Draft
Type: Informational
Created: 2019-06-04
Discussion: https://github.com/bitshares/bsips/issues/172

Abstract

We describe a methodology for implementing short-lived one-way payment channels on top of the BitShares protocol. Payment channels are a construct that allows a payment to be initiated, negotiated, and finalized in distinct steps, with only the initiation and finalization phases needing to occur on-chain. The negotiation phase, which may comprise numerous incremental payments, happens off-chain via sideband communication, where parties exchange "claims" against a balance reserved in the channel. Payment channels are a way to handle a large volume of payment operations without the attendant chain load that would occur if those transactions were conducted on-chain.

The payment channel methodology proposed in this document depends upon a very minor upgrade to the existing BitShares core protocol, which is described separately in BSIP-0069: Additional Assert Predicates. Apart from this one small upgrade, the methodology is based entirely on existing features of the BitShares core protocol. The needed protocol addition supplements the existing 'assert' operation with a new predicate that would allow a transaction to assert a minimum head block time, chosen to be in the future at the time of transaction creation. This allows a "time lock" to be placed on a transaction, and this, in turn, makes possible the payment channel protocol. We describe a "short-lived" payment channel methodology, where the maximum lifetime of the channel is constrained by the core protocol requirement that a transaction include a "TaPoS" parameter identifying a reference block occurring within the last 2^16 blocks at time of transaction broadcast. This sets a maximum possible channel lifetime at approximately two days (with useful channels being a bit shorter, to allow a window in which to broadcast the time-locked transaction). By comparison, a "long-lived" payment channel protocol could additionally be developed, but this would require a much more significant protocol upgrade to enable functionality. Thus a primary advantage of short-lived channels is that they can be implemented now (pending BSIP-0069). Furthermore, we note that there are in fact interesting use cases wherein a two-day lifetime 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.

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 transfer operations 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. However, on-chain settlement operations for such low-valued transfer amounts could prove expensive. Indeed, 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. The key benefit of a payment channel is that it allows this type of settlement operation to be negotiated off-chain, and yet preserves the security assumptions of an on-chain transaction.

Thus what we describe below is a payment channel construct in which we may open a channel in a single on-chain transaction, negotiate state in a side band, (including, possibly, thousands of individual channel-state updates), and 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 on-chain transactions.

Rationale

Why Short-Lived Channels?

Why Unidirectional Channels?

Specifications

The channel methodology depends on having a container for funds that is constrained by a multisignature authority. For this purpose, we can simply use an account object, which one party to the channel (typically the sender) will need to have registered in advance. During use of an account object as a payment channel, the account's owner authority should be set as a 2-of-2 multisig between public keys (NOT account names) of the two parties to the channel, and the account's active, special, and custom authorities should all be null. After close of a channel, the owner authorities can (and should) be reverted to the original party that registered the account. This will allow the account object to be reused by the originator for future channels.

In what follows we assume that the two parties, we'll call them Alice and Bob, are in communication with each other via a mechanism of their choice, which we'll call the Payment Channel Communication Layer (PCCL). Generally, this communication will be handled by the wallet software, and the method of communication, as well as the messaging formats, are not specified in this document. (This BSIP proposes a methodology, not a complete protocol.) A wallet developer would be expected to develop an adequate specification for the communication side, including channel handshaking, keepalive, and parameter negotiation. This document details primarily the blockchain interaction and the transactions and data structures that need to be exchanged over such a communication layer in order to enable the payment channel.

Opening and Funding a Channel:

One-time setup:

Per-channel setup:

Transaction:
TaPoS (a recent block)
Tx Expiration (now) + (channel lifetime) + (refund window),
_where (refund window) <= maximum_time_until_expiration_
Operations:
1. Assert block_time > (now) + (channel lifetime)
2. Transfer 100 bitUSD from alice-to-bob-pc to alice
3. Update Authority Revert to: [[‘alice’, 1] 1]
Operations:
1. Transfer "enough" BTS from alice to alice-to-bob-pc to cover anticipated fees.
2. Transfer 100 bitUSD from alice to alice-to-bob-pc
3. Update Authority [[alice-pubkey, 1], [bob-pubkey, 1], thresh: 2] on account alice-to-bob-pc

Notes:

Updating State:

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

Initial state:

Alice sends Bob $1.00:

Transaction:
TaPoS (a recent block)
Tx Expiration (now) + (closeout window)
Operations:
1. Transfer 99 bitUSD from alice-to-bob-pc to alice
2. Transfer 1 bitUSD from alice-to-bob-pc to bob
3. Update Authority Revert to [[‘alice’, 1] 1]

Alice sends Bob another $1.00:

Transaction:
TaPoS (a recent block)
Tx Expiration (now) + (closeout window)
Operations:
1. Transfer 98 bitUSD from alice-to-bob-pc to alice
2. Transfer 2 bitUSD from alice-to-bob-pc to bob
3. 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 incentivized 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 (for example, if 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 the previously-signed REFUND and STATE_UPDATE transactions. This can be achieved by updating the account authorities of alice-to-bob-pc to a NEW pair of public keys supplied by Alice and Bob.

By way of example, let's assume the latest STATE_UPDATE of the channel was 98 bitUSD signed over to Bob from Alice. This means the current state is:

Alice still has 2 bitUSD in the channel which she has not yet signed over to Bob. Let's say Alice wants to add 198 bitUSD to the channel, so that the end result will be a channel pre-funded to 200 bitUSD. In order to invalidate the previous REFUND and STATE_UPDATE transactions, Alice first asks Bob to provide her with a new public key. Bob responds by sending bob-pubkey-02 to Alice. Alice then constructs a new REFUND transaction as follows:

Transaction:
TaPoS (a recent block)
Tx Expiration (now) + (channel lifetime) + (refund window)
Operations:
1. Assert block_time > (now) + (channel lifetime)
2. Transfer 200 bitUSD from alice-to-bob-pc to alice
3. Update Authority Revert to: [[‘alice’, 1] 1]

Bob is safe to sign this transaction with bob-pubkey-02 because he is protected by the time-lock and by the fact that the account is not yet controlled by bob-pubkey-02. So Bob sends his signature back to Alice.

Alice now constructs the following REVOKE_AND_REBALANCE transaction:

Transaction:
TaPoS (a recent block)
Tx Expiration (now) + (time enough for multisig round with bob)
Operations:
1. Transfer "enough" BTS from alice to alice-to-bob-pc to cover anticipated fees.
2. Transfer 198 bitUSD from alice to alice-to-bob-pc
3. Transfer 98 bitUSD from alice-to-bob-pc to bob
4. Update Authority [[alice-pubkey-02, 1], [bob-pubkey-02, 1], thresh: 2] on account alice-to-bob-pc

Alice signs the transaction with her 'alice' account and with alice-pubkey, and then sends the transaction and signatures to Bob, who inspects them for correctness and fairness, then signs with bob-pubkey, and then broadcasts.

The side-effects of the REVOKE_AND_REBALANCE transaction are as follows:

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, and optionally absent the cash-out transfer operation (saves a transfer fee), provided Alice also provides Bob a new STATE_UPDATE transaction signed with her new public key along with the REVOKE_AND_REBALANCE transaction.

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 (formerly) time-locked REFUND transaction.

Closing the channel is simply a matter of signing and broadcasting the latest STATE_UPDATE transaction 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 prior to the expiration time of the REFUND transaction, or else the transaction will become invalid. (Should this happen, she may informally, of course, negotiate with Bob 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 principle, negotiate a settlement transaction to disburse the funds as intended, although they do run the risk of deadlock if they cannot come to an agreeable course of action. Wallet software can be coded to respond to this situation automatically and fairly with a channel extension procedure, so that users can expect a fair outcome so long as both parties are using un-modified wallet software.

Changes to fees and parameters

Since BitShares uses explicit fees in the transactions, the partially-signed time-locked refund transactions and partially-signed channel 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 could become invalid if they pay inadequate fees under the new schedule. If this happens, the most probable scenario is that both the sender's refund transaction and the receiver's update transactions have been invalidated, (although it is possible for only the sender's refund transaction to be invalidated, if the change increases fees for the 'assert' operation, but not for 'transfer' or 'account_update'). In this scenario, the parties MUST cooperate in order to recover the funds and the channel. Ideally, the sending party should send the receiving party a new signed STATE_UPDATE transaction paying the appropriate fees, prior to requesting a signature from the receiving party on a new REFUND transaction. (Otherwise the sending party will have a "take all" option before the receiving party has received a fair "cash out" option.) If the payment channel's BTS balance is inadequate, it is possible that one of the parties may need to top up the channel's BTS balance to cover the new fees prior to this interaction. Either party may do this unilaterally. In general, wallet software implementing payment channels should be designed to handle these situations automatically and cooperatively so that the user need not have to take manual intervention. Questions such as who is expected to top off fees in this situation should be decided in advance during the handshaking phase of opening a channel, so that wallets can simply act to revive the channel.

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.) This is a more difficult situation to respond to. However, this is an unlikely parameter to be modified, and the committee would be advised to exercise extreme caution in considering such a modification. Ample warning time and discussion would be advised.

Summary for Shareholders

This BSIP describes a methodology for implementing payment channels for efficiently handling high volumes of incremental transactions between two parties with a minimum of on-chain transactions, thus reducing blockchain load and reducing fees paid by the two parties. The methodology covers the mechanics of opening and funding a channel (on-chain), exchanging state-update transactions (off-chain), optionally rebalancing or extending the lifetime of a channel (on-chain), and finally closing a channel (on-chain). This document does NOT specify details of the communication layer or the messaging protocol between parties. When combined with a suitable communication layer and messaging protocol, this payment channel methodology can be developed into a full payment channel protocol, which can be used to bring features such as streaming micropayments and connectivity to the Interledger network to the BitShares platform, which opens up possibilities for cross-ledger payments and swaps, and may allow for the development of new trustless or nearly-trustless gateways for deposits and withdrawals of off-chain assets for their on-chain counterparts.

The methodology builds upon existing core protocol features and requires no significant upgrades to the core protocol beyond a minor and presumably uncontroversial upgrade to the 'assert' operation detailed in BSIP-0069.

This BSIP describes a methodology for short-lived unidirectional payment channels. This type of payment channel meets the requirements for connection to the Interledger network. More sophisticated long-lived and/or bi-directional payment channel protocols may in the future offer some efficiency gains or open up additional use cases. However, long-lived channels would require a significant upgrade to the BitShares core protocol, whereas short-lived channels do not.

Copyright

This document is placed by its authors in the public domain.

See Also

pmconrad commented 5 years ago

Excellent! A very interesting protocol, thanks!

Some remarks:

@ryanRfox please assign BSIP number.

ryanRfox commented 5 years ago

Assigned BSIP63

A PR may now be created based on the text in the description.

xeroc commented 5 years ago

This looks like a hack. Why not setup a new "channel" as a object and have the keys of Alice and Bob be part of that new object. That way you can lock away funds already and don't need to ensure (like @pmconrad says) that no BSIP40 authority has been granted to the "channel account".

Or do I misunderstand something?

pmconrad commented 5 years ago

It is a hack, in the sense that it uses (mostly) existing functionality in an unforeseen way to produce something new. I. e. it's a good hack. :-)

The only missing piece is a simple but generic assert operation for implementing the time lock.

thontron commented 5 years ago

Would every "Update State" between the parties result in cumulative "transfer" fees?

ryanRfox commented 5 years ago

No. Updates are P2P off-chain. Only the open (funding) and close (settling) are on chain and assessed a fee.

thontron commented 5 years ago

Okay that is helpful - thank you.

Let's say Alice and Charlie both have payment channels open with Bob. Rather than updating state directly with Bob, may Alice share a transfer directly with Charlie?

There is the concept of potential "negative fees" for this type of payment routing. I'm wondering if the fees are just baked into the updated state because there is no on-chain fee outside of settlement.

thontron commented 5 years ago

Finally understanding this more - so above question is probably not much sense.

Is there a particular wallet that is good for creating the "bailout" transaction and other "update state" transactions. I don't think ref UI permits this exportation of operations.

Thanks!

ryanRfox commented 4 years ago

@christophersanborn Please create a PR for this using your latest text. It seems "done" to me. It depends on BSIP69 for the required assert predicate, but feel they can be considered in tandem.

christophersanborn commented 4 years ago

Made some significant revisions (mainly filling out missing details, clarifying language), and created PR #219.

abitmore commented 4 years ago

Draft merged in #63. Closing the issue.