[Lightning-dev] Improving Payment Latency by Fast Forwards

ZmnSCPxj ZmnSCPxj at protonmail.com
Sun May 23 07:26:30 UTC 2021


Good morning list,

I have decided to dabble in necromancy, thus, I revive this long-dead thread from two years ago.
Ph34R mE and my leet thread necromancy skillz.

A short while ago, LL and Steve Lee were discussing about ways to reduce the privkey onlineness requirement for Lightning.
And LL mentioned that this proposal could allow privkeys to be kept offline for a receiver.

* The receiver has to be online, still.
* Its privkeys can be kept offline.
  * The receiver can still receive even if its privkeys are offline (for example the privkeys are in a hardware signing module that is typically kept offline and is only put online at rare intervals).
* The sender has to be online and the sender privkeys have to be online.
* Forwarders and their privkeys have to be online.

Unfortunately, I think the proposal, as currently made, cannot support the above feature, as stated.

When an HTLC transaction is provided by the sender under a Fast Forward scheme, it provides a transaction that spends from "its" output in both versions of the latest Poon-Dryja commitment transaction.

However, this output, as provided in the Fast Forward scheme, requires *two* signatures.

Here are the scripts mentioned in the previous post:

    OP_IF
        # Penalty transaction/Fast forward
        <local_revokepubkey> OP_CHECKSIGVERIFY <remote_penaltyclaimpubkey>
    OP_ELSE
        `to_self_delay`
        OP_CSV
        OP_DROP
        <local_delayedpubkey>
    OP_ENDIF
    OP_CHECKSIG

And:

    OP_IF
        # Penalty transaction/Fast forward
        <local_revokepubkey> OP_CHECKSIGVERIFY <remote_penaltyclaimpubkey>
    OP_ELSE
        `to_self_delay`
        OP_CSV
        OP_DROP
        <remote_delayedpubkey>
    OP_ENDIF
    OP_CHECKSIG

Now, the first branch is what is used in the Fast Forward scheme.
And we can see that in the first branch, two signatures are needed: one for local, and one for remote.

Thus, any HTLC-bearing transactions are signed by both the sender and receiver.
Fast Forwards works its low-latency magic by simply having the sender send the signature spending from the current channel state, outright, to the receiver, and until the channel is updated, the HTLC is "safe":

* The current channel state (represented by some commitment tx) cannot be replaced with an alternative, without the replacer risking funds loss (Poon-Dryja punishment mechanism).
* The spending tx that instantiates the HTLC is safe because the receiver will not willingly sign an alternate version.

***HOWEVER***, the HTLC is safe on the assumption that *the receiver can provide its signature* if the channel is dropped onchain.
And channels can be dropped onchain *at any time*.
If the receiver is unable to provide its signature before the `to_self_delay` finishes, then the sender can revoke ***all*** HTLCs it sent!

Thus, at least as initially stated, Fast Forwards cannot be used for this "receiver online, privkeys offline, can receive" feature.

***HOWEVER HOWEVER***, we should note that the caveats are something we can actually work with:

* The privkeys can only be offline for up to `to_self_delay` blocks.
  * We ***need*** privkeys to be periodically online more often than `to_self_delay` anyway, ***in case of theft attempts***.
    So this is not an ***additional*** requirement at least.
* Watchtowers cannot guard against attempts to steal Fast Forwarded HTLCs --- they need to receive the signatures for the HTLC transactions as well, otherwise they can do nothing about it.
  * However, whenever the receiver sends to a watchtower it *does* need to send signatures anyway, so it still needs to get privkeys online for signing.
  * Since we need the privkeys to be made online a little more often than every `to_self_delay` blocks anyway, this is *not* an additional requirement!

***THUS***, we *can* provide a tweaked version of the above desired feature:

* The receiver has to be online, still.
* Its privkeys can be kept offline, ***BUT***, it has to be regularly brought online a little more often than `to_self_delay`.
  * The receiver can still receive even if its privkeys are offline (for example the privkeys are in a hardware signing module that is typically kept offline and is only put online at rare intervals).
* The sender has to be online and the sender privkeys have to be online.
* Forwarders and their privkeys have to be online.

The additional requirement --- that the receiver privkeys have to be regularly brought online --- is not actually an onerous one *since we need it for channel safety*.

So this feature is indeed supported by Fast Forwards (with fairly minimal caveats!) and kudos to LL for thinking of it!

Against this, we should remind the drawbacks of Fast Forwards:

* Onchain space is much higher (in the unilateral close case only --- channel opens and mutual closes remain small) due to chaining of transactions instead of strict replacement.
* Fast Forwarded HTLCs need to have their signatures stored on replicated storage, and is O(n) (current Poon-Dryja requires O(1) storage for revocation keys but O(n) storage for HTLC hash/timelock details).
  If you lose your data storage, you lose received HTLCs, including those whose preimages you have already released.

For this, we should also take note that:

* Payment latency is greatly improved.
* The above "receiver online, receiver privkeys offline, can receive" feature is now possible, with the caveat:
  * The privkeys need to be periodically brought online for short amounts of time in order to "collapse" chains of HTLC transactions, recover from theft attempts, and update watchtowers etc.

---

Now, Fast Forwards is a scheme that is designed for a modified form of Poon-Dryja.

Unfortunately, at least for now, it seems the scheme cannot be used in Decker-Russell-Osuntokun ("eltoo").

In particular, Fast Forwards work because it is safe (and even required!) for a Poon-Dryja scheme to impose timeouts on the "main" outputs of a channel.
And those timeouts have a branch that is a 2-of-2 between the channel participants.
That branch is where Fast Forwards hook into.

In Decker-Russell-Osuntokun, the "main" outputs are not encumbered by any timeouts; they are simple singly-signed outputs.
The timeout is instead placed "before" the state transactions that contain the "main" outputs.
The HTLC transactions are not safe without a 2-of-2, as otherwise the sender could just spend the main output to a different address, removing the HTLC.

Because of this, the "main" output of a Decker-Russell-Osuntokun cannot be used in a Fast Forwarded manner, as the Fast Forwarded transaction needs to be signed by both participants.

We *could* add *another* timeout at the main output simply to support Fast Forwards, using a similar "2of2 or OP_CSV+singlesig".
However, this increases the effective delay in the case the channel is dropped unilaterally onchain.

In addition, we should remind that when forwarding, Decker-Russell-Osuntokun requires that the CLTV at a particular hop be larger than the `to_self_delay` at that hop i.e. it imposes a "minimum CLTV" cost that is combined with `max` instead of `+`, which pathfinding algorithms (that I know of) are totally not designed for.

Furthermore, properly designed, a Decker-Russell-Osuntokun construction could also have payment latency approaching the latency of the Fast Forward scheme, so that advantage of Fast Forwards is lost as well, so we are paying for more inconvenience for a smaller feature set (only the "receiver online, privkey offline" feature remains; maybe worth it?).

Of note, is that there also exists a Poon-Dryja variant that has a similar structure to Decker-Russell-Osuntokun (and has the same drawback of requiring a "minimum CLTV" at each hop) --- Fast Forwards would also not work well with that particular Poon-Dryja variant, too.


Regards,
ZmnSCPxj


More information about the Lightning-dev mailing list