[Lightning-dev] Clearing process in BOLT #2

Rusty Russell rusty at rustcorp.com.au
Sat Apr 30 10:11:34 UTC 2016


Pierre <pm+lists at acinq.fr> writes:
> Hello,
>
> I see a few issues with the clearing process as currently described in BOLT #2.
>
> There seem to be a contradiction between:
>   §4.1 "A node MUST respond with update_fail_htlc to any HTLC received
> after it sent close_clearing."
> and:
>   §3.3 "There are three reasons for removing an HTLC: it has timed
> out, it has failed to route, or the R preimage is supplied.")
>   §3.3 "A node MUST check that id corresponds to an HTLC in its
> current commitment transaction."

Hi!

        Hmm, 4.1 should say: "A node must fail to route any HTLC
received after it sent close_clearing".  Basically, once you announce
you're shutting down the channel, you don't accept any more routes.  You
could still receive them, because the other node might not have received
your "close_clearing" yet.

> In §4.1, the node must decline/remove the still-uncommitted HTLC,
> which is explicitely forbidden by §3.3.

That was not the intent of 4.1; all responses are delayed until receipt
of `update_commit`.

> AFAICT, in this version of the
> procotol an HTLC can only be accepted, then committed, then removed.
> There is no way to decline an HTLC, the receiver must always accept it
> except when the sender doesn't have the money or there are two many
> pending HTLC, in which case the connection should be failed (§3.2,
> although it is actually not clear for the too-many-htlc case).

It's the same with a node sending you an HTLC with too short a timeout
or insufficient fee.  There's no harm in you signing the *offer*; you're
just not going to redeem it.

Too-many-htlcs is a protocol violation, OTOH, and fail immediately.

> We could decide to just fail the connection instead of declining the
> htlc, but there is another issue: if the sender of a "close_clearing"
> message subsequently receives an update_add_htlc, there is no way to
> tell if the other party had received the close_clearing prior to
> sending the htlc since update_add_htlc message doesn't have an 'ack'
> field.

Yes, this is why we don't have a "that HTLC will fail" message.  We
*could* add one, but it would be advisory only, and require the
originator to send a "HTLC_UNADD" (?) message.

Since failure should be an unusual case, I considered that a premature
optimization.

> There is potentially the same issue with the signature process: when
> node A sends an update_commit message to B, it is expecting an
> update_revocation rather sooner than later. But what if B just ignores
> the update_commit message and keeps sending new htlcs ? There is no
> way for A to be sure that B indeed received the update_commit, for the
> same reason as above.

The intent was that B can't get more than one step ahead.  But I didn't
say that explicitly.  Patch below.

B could ignore update_commit.  But to make progess, at some point it has
to send update_commit to A.  Then A sends update_revocation.

Now, B can keep sending more htlcs to A, but it *can't* send another
update_commit, because you're not allowed to send it without receiving
the previous update_revocation.  So it has to ack it at that point.

(My implementation never sends htlcs while waiting for an
update_revocation, but it is explicitly legal, to allow more optimal
pipelining).

Here's the diff, I hope it clarifies.

Thanks!
Rusty.

diff --git a/bolts/02-wire-protocol.md b/bolts/02-wire-protocol.md
index e48aa1a..637bec1 100644
--- a/bolts/02-wire-protocol.md
+++ b/bolts/02-wire-protocol.md
@@ -484,6 +484,11 @@ staged changes, it generates the other node's commitment transaction with those
 
 A node MUST NOT send an `update_commit` message which does not include any updates.  Note that a node MAY send an `update_commit` message which only alters the fee, and MAY send an `update_commit` message which doesn't change the commitment transaction other than the new revocation hash (due to dust, identical HTLC replacement, or insignificant or multiple fee changes).
 
+A node MUST acknowledge the previous `update_revocation` (if any) in
+the `update_commit` message.  A node SHOULD fail the connection if it
+receives an `update_commit` which does not acknowledge its previously
+sent `update_revocation`.
+
 A node MUST NOT send out a message with an `ack` field lower than any
 previous `ack` field.
 
@@ -647,7 +652,7 @@ Either node (or both) can send a `close_clearing` message to initiate closing:
 A node MUST NOT send a `update_add_htlc` after a `close_clearing`, and
 must not send more than one `close_clearing`.  A node SHOULD send a `close_clearing` (if it has not already) after receiving `close_clearing`.
 
-A node MUST respond with `update_fail_htlc` to any HTLC received after it sent `close_clearing`.
+A node MUST fail to route any HTLC added received after it sent `close_clearing`.
 
 ### 4.1.1. close_clearing message format
 


More information about the Lightning-dev mailing list