[Lightning-dev] Witness asymmetric payment channels

ZmnSCPxj ZmnSCPxj at protonmail.com
Tue Aug 25 12:45:50 UTC 2020

Good morning Lloyd,

I think this is excellent work overall.

With that said...

> -   It is more elegant as there are half the number of possible transactions. I
>     expect this will follow through to reduced implementation complexity and maybe
>     make it easier to explain as well.

I am not sure the complexity will be reduced all that much.


* We provide a partial signature for the other side for their commitment transaction.
* We keep our own commitment transaction and the partial signature we receive from the other side.

The node never has to retain the commitment transaction of the other side.

With this setup:

* We provide a partial signature for the other side for their asymmetric signature.
* We keep a copy of the shared commitment transaction and the partial signature we received for our own asymmetric signature from the other side.

So storage complexity is still the same.

An issue is that with asymmetric transactions, it is fairly easy to use TCP to communicate changes to the commitment txes.
We send a bunch of HTLC changes we want to apply to the other side commitment tx, then send a signature for those changes.
Since what we send applies to *their* transaction only, we do not have to consider what they sent to us, we just have to consider what we sent to them.
Conversely, when keeping track of what our commitment transaction is, we only have to consider what they sent to us, in order, and then when we receive a signature we know it is for the commitment transaction with all the updates the other side sent.

(This arguably just moves the complexity higher, however: we cannot forward an HTLC until both us and the other side have revoked the transactions that do not contain it i.e. the "irrevocably committed" state.)

When we have "the same" transaction on both sides, however, we need to synchronize between the two sides.
Suppose both participants want to forward HTLCs to one another.
Without any kind of locking, both participants could send network packets containing the HTLCs they want to add to each other, and it becomes ambiguous whether the signature they *should* send contains one, or both.

Basically, TCP only assures a global order for *one* direction of the communications, once we have two network nodes talking simultaneously, the order in which one writes and then reads is a lot more ambiguous.

This issue also exists for Decker-Russell-Osuntokun, incidentally.

One way to solve this would be to have a "token" that is passed alternately between the participants.
At initial connection, they run a secure multiparty coinflip that indicates which one gets the token.
Then, the one that holds the token can add more HTLCs, then tell the other "okay, now we sign" and they exchange signatures for a new version that involves only the HTLCs from the token-holder.
Then the token-holder passes the token to the other side.

If the current token-holder does not have any HTLCs it wants to send, it can wait for some time (in case it receives a request to forward), then if there are still no HTLCs, it can pass the token to the other side by sending a token-passing message.

This solution requires a good amount of bandwidth in such token-passing messages, which can multiply with the number of channels a single node has.
If token-passing is not done in short time frames (sub-second) then it potentially increases the latency of forwarding, thus this represents a latency vs bandwidth tradeoff.

There may be better solutions for this race-condition problem.
For example, it seems to me that we can still have different histories for both sides of the channel, i.e. different transactions on both sides, the same as in current Poon-Dryja BOLT.
After all, the witnesses are asymmetric anyway.
But that completely negates the stated goal of removing the different transactions on both sides and the hoped-for reduction in complexity, so an exercise in futility.


More information about the Lightning-dev mailing list