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
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.
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.
Why Short-Lived Channels?
- Long-lived channels would require a significant BitShares protocol upgrade. Short-lived channels do not.
- Since 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 by economics to keep channels open. 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, and can use a short-lived channel as the settlement layer.
Why Unidirectional Channels?
- Simplicity. No analog to Bitcoin's “check sequence verify” is needed to prevent a dishonest party from broadcasting an earlier channel state. Since funds flow in only a single direction, the receiving party is naturally incentivized against broadcasting an earlier state, and the sending party has no ability to do so until after the 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 easily be done in a separate channel.
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.
One-time setup:
- Sender Alice registers an account to serve as the channel. This will allow for multisignature authorities to be constructed. She may use this account multiple times for independent payment channels, provided they are not open simultaneously.
- Create Account:
alice-to-bob-pc
- Initial Authority:
[[‘alice’, 1], thresh: 1]
- Initial Balance: 0
- Initial Authority:
- Create Account:
Per-channel setup:
- Alice, as the sending party, wishes to initialize a channel to Bob and pre-fund it with 100 bitUSD (the maximum she anticipates sending to Bob at this time). Alice asks Bob for a unique public key under Bob’s control to use in the channel authority, which Bob provides to Alice over the communication layer.
- Alice constructs an unsigned (and as-yet invalid due to the time-lock) transaction with the following THREE operations. This will be Alice's "Time-Locked REFUND Transaction", and allows her to recover channel funds if Bob fails to close the channel prior to channel expiration.
- The channel expiration time will be established via the assert operation, which ensures Alice can only trigger a refund after the asserted time. She will want to ensure that the channel expiry is sufficiently prior to the TaPoS limit so that she will have an adequate refund window in which to broadcast the refund transaction.
- Alice will want to ensure that the transaction expiration time is beyond the channel expiration time by at least as much time as the intended refund window, but NOT more than the blockchain parameter
maximum_time_until_expiration
, as this could unwittingly invalidate the transaction.
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] |
- Sender Alice then transmits the transaction JSON to Bob over the PCCL and asks Bob for a signature on that transaction.
- Bob verifies that the transaction is correctly constructed and returns a signature to Alice.
- Alice verifies that the signature provided by Bob is valid and comes from the key he previously provided to her.
- As Alice now has Bob's signature on a (future-dated) REFUND transaction, Alice is now safe to fund the channel. So she broadcasts a CHANNEL_BALANCE transaction composed of the following three operations:
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 |
- 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
tobob
.
Notes:
-
Timelock: The timelock for the REFUND transaction is enforced by the assert operation. It is important that this is at or 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 parameter, so as to give Alice a time window in which to close out if Bob disappears.
-
Fee payer: In the example above, Alice has funded the payment channel with BTS to cover anticipated fees (the fees that will be needed to close out the channel). It is possible that the parties may wish for the receiving party to cover these fees, rather than the sending party. In this case, Alice should construct the CHANNEL_BALANCE transaction to use 'bob' as the sending party for the BTS transfer. Alice will not be able to unilaterally broadcast the transaction anymore, however she can instead send the transaction to Bob, along with her own signature. Then Bob can append his signature and broadcast, at which point the channel will be created.
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 has: Time-locked REFUND transaction
- Bob has: (Nothing)
Alice sends Bob $1.00:
- Alice has: Time-locked REFUND transaction
- Alice gives Bob a half-signed Tx with the following operations:
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] |
- The timeframe (closeout window) is the window within which Bob will need to broadcast the transaction if he wishes to close the channel with the given state, and is a parameter that Alice and Bob should agree upon during communication at the opening of the channel, and should be chosen by Bob, and may perhaps be updated by Bob during channel lifetime via messaging over the PCCL. Generally speaking, (closeout window) will be equal to
maximum_time_until_expiration
, but could be longer or shorter at Bob's option. Bob may choose a longer window if he wishes extra time to close the channel (though it comes at a cost of introducing a delay before the closeout transaction would become valid). Or Bob may choose a shorter window if he wishes some protection against the unlikely event that the committee-controlledmaximum_time_until_expiration
parameter could be shortened during the lifetime of the channel. Note that at the present timemaximum_time_until_expiration
is set to 1 day, and the TaPoS limit is approximately 2 days, assuming regular block production with no missed blocks.
Alice sends Bob another $1.00:
- Alice has: Time-locked REFUND transaction
- Bob has: An earlier STATE_UPDATE transaction with Alice's signature
- Alice now gives Bob a new partially-signed Tx with the following operations:
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.
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 has: The original REFUND transaction (100 bitUSD --> 'alice'), signed by
bob-pubkey
, still under time-lock. - Bob has: A STATE_UPDATE transaction (98 bitUSD --> 'bob', 2 bitUSD --> 'alice'), signed by
alice-pubkey
.
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:
- Bob has received the 98 bitUSD that had to that point been signed over to him in the payment channel.
- The previous REFUND and STATE_UPDATE transactions have been revoked, as their signatures are now invalid (the account authority has been updated to new keys).
- The channel is now funded to 200 bitUSD, and Alice may continue to communicate new STATE_UPDATE transactions to Bob, just as before, incrementally signing the new channel funding over to Bob.
- The lifetime of the channel has been extended, since the new REFUND transaction references a new TaPoS block, and asserts on a new future-dated block time.
- If more BTS were needed to cover fees, they have been added.
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.
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.)
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.)
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.
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.
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.
This document is placed by its authors in the public domain.