[Lightning-dev] HTLCs using OP_CHECKSEQUENCEVERIFY/OP_LOCKTIMEVERIFY and revocation hashes.

Rusty Russell rusty at rustcorp.com.au
Mon Jul 6 06:41:34 UTC 2015


Hi all,

        To recap: each side maintains a commitment transaction with two
outputs: one paying to self (with some delay), and the second paying to
the other side.

        To generate hash time-locked contracts (required for lightning
to be a network), both commitment transactions get an additional output.
This output is spendable under four conditions:

1) Recipient knows the R value (funds go to recipient), OR
2) The HTLC has timed out (funds return to initiator), OR
3) The HTLC has been revoked (funds to go "non-cheating" side), OR
4) The Commit transaction has been revoked (funds to go "non-cheating" side)

The last two failure modes are separate from each other, because HTLCs
have different lifetimes from commit transactions.

Since we use "revocation preimages" to revoke transactions (rather than
sending pubkeys as the original draft paper), the result of this for A's
commitment transaction look like this:

HTLC from A to B:
1) R value and B's signature, OR
2) HTLC timeout and A's signature[*], OR
3) HTLC revocation preimage and B's signature, OR
4) Commitment transaction revocation preimage and B's signature.

HTLC from B to A:
1) R value and A's signature[*], OR
2) HTLC timeout and B's signature, OR
3) HTLC revocation preimate and B's signature, OR
4) Commitment transaction revocation preimage and B's signature.

We need to ensure delays in the cases where payment can go to A (marked
with [*]) so that B has a chance to steal the funds if the HTLC or
commitment tx has been revoked.

The result is one of the following scriptPubKey from the commitment tx
for the HTLC like so (note: unchecked and unoptimized!):

HTLC from US to THEM:
---------------------

# They present HTLC's R value, or either revocation hash:
OP_DUP OP_HASH160 <HTLC-R-HASH> OP_EQUAL
OP_SWAP <HTLC-REVOCATION-HASH> OP_EQUAL
OP_ADD OP_SWAP <COMMIT-REVOCATION-HASH> OP_EQUAL
OP_ADD
OP_IF
        # One hash matched, pay to them.
        OP_DUP OP_HASH160 <THEM-pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
OP_ELSE
        # Must be us, with HTLC timed out.
        <HTLC-ABSOLUTE-TIMEOUT> OP_CHECKLOCKTIMEVERIFY OP_DROP
        <VERIFICATION-RELATIVE-TIMEOUT> OP_CHECKSEQUENCEVERIFY OP_DROP
        OP_DUP OP_HASH160 <US-pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
OP_ENDIF

HTLC from THEM to US:
---------------------
# Revocation cases:
OP_DUP OP_HASH160 <HTLC-REVOCATION-HASH> OP_EQUAL
OP_SWAP <COMMIT-REVOCATION-HASH> OP_EQUAL
OP_ADD
OP_IF
        # One hash matched, pay to them.
        OP_DUP OP_HASH160 <THEM-pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
OP_ELSE
        # Us with R value?
        3 OP_DEPTH OP_EQUAL OP_IF
                OP_DUP OP_HASH160 <HTLC-R-HASH> OP_EQUALVERIFY
                <VERIFICATION-RELATIVE-TIMEOUT> OP_CHECKSEQUENCEVERIFY OP_DROP
                OP_DUP OP_HASH160 <US-pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
        OP_ELSE
                # Them with timeout.
                <HTLC-ABSOLUTE-TIMEOUT> OP_CHECKLOCKTIMEVERIFY OP_DROP
                OP_DUP OP_HASH160 <THEM-pubKeyHash> OP_EQUALVERIFY OP_CHECKSIG
        OP_ENDIF
OP_ENDIF

If you've read this far, congratulations!

AFAICT we don't need new SIGOPS here; the logic has all been moved to
the commitment transaction output (thanks to OP_CLV and OP_CSV), so each
side can generate the HTLC spending transaction with needing a signature
from the other.

Feedback, fixed and optimizations welcome...
Rusty.


More information about the Lightning-dev mailing list