<h1>TL;DR</h1>
<p>Because it would create a nasty dependency of the CLTV deltas over the CSV delay or a reduced security for HTLCs.<br />
Having the revocation path in the second-stage transaction allows to be able to timeout an HTLC (ie your peer cannot redeem it via pre-image anymore) while still leaving the revocation period (CSV) intact for you to be punished if you cheated.</p>
<h1>Two-stage HTLCs</h1>
<p>The Lightning Network protocol makes use of two-stage HTLCs.<br />
<em>Why</em>: allow to use absolute timelock delta shorter than the relative timelock delta used for the fundamental security model (punishment), without degrading the security model for HTLC outputs.<br />
<em>How</em>: make (basically) HTLC outputs pay to either the revocation path, the [timeout/success] transactions only broadcastable after block <code>B</code>, or the receiver with the preimage. Make the [timeout/success] transaction pay only after full expiration of the revocation period (no preimage path anymore here, if the receiver did not cheat they <strong>will</strong> get paid).</p>
<p>More about two stages HTLCs in <a href="https://bitcoin.stackexchange.com/a/95543/101498">this answer</a>.</p>
<h1>Why put the revocation path at both stages ?</h1>
<p>Because the first stage expires at the end of the absolute timelock period, which is likely to be less than the revocation period.<br />
If the revocation path was not present in the second transaction (which is actually the point of using two stages) then you would either drastically reduce the revocation period for HTLC outputs, or require using insanely high CLTV deltas.</p>
<h1>An example</h1>
<p>I've a channel with you, and we agreed on a <a href="https://github.com/lightningnetwork/lightning-rfc/blob/master/02-peer-protocol.md#the-open_channel-message" rel="nofollow noreferrer"><code>to_self_delay</code></a> of 144 blocks (1 day to punish the broadcast of a revoked state) and a (reckless) <a href="https://github.com/lightningnetwork/lightning-rfc/blob/master/02-peer-protocol.md#cltv_expiry_delta-selection" rel="nofollow noreferrer"><code>cltv_expiry_delta</code></a> of 6 blocks.</p>
<p>I just attempted to make a payment through our channel. We appended an <a href="https://github.com/lightningnetwork/lightning-rfc/blob/master/03-transactions.md#offered-htlc-outputs" rel="nofollow noreferrer">offered HTLC output</a> to my commitment transaction and a <a href="https://github.com/lightningnetwork/lightning-rfc/blob/master/03-transactions.md#received-htlc-outputs" rel="nofollow noreferrer">received HTLC output</a> to yours.<br />
Let's say someone found funny to not take its negligible fees and instead stuck the HTLC to mess with us. After 4 blocks, we fail the HTLC, sign a new pair of commitment transactions and continue operations --I'd later learn that <strong>you</strong> actually stuck the HTLC just after gathering the preimage.</p>
<p>We don't create new states to our channel and the same night I suffer a power outage, my node comes offline and I don't notice it until I'm awake (5 hours later).<br />
At the exact moment I got offline you took the absolutely irrational decision to broadcast your ancient commitment transaction in which you still have a signed received HTLC output.<br />
Your transaction gets confirmed, and passed the 6 blocks (still 4 hours until I wake up) you can claim the output with your HTLC success transactions.</p>
<p>4 hours later, I wake up, put my <a href="https://lightning.readthedocs.io/PLUGINS.html#db-write" rel="nofollow noreferrer">continuously backed up</a> node back online and notice the breach.<br />
Before I could even have the time to feel disillusioned, disappointed and frustrated enough to throw swear words to a <a href="https://github.com/lightningnetwork/lightning-rfc/blob/master/07-routing-gossip.md#the-node_announcement-message" rel="nofollow noreferrer">random internet colored alias</a>, my node stole your coins from your commitment transaction's <code>to_self</code> output, claimed my <code>to_remote</code> output and spent your HTLC success transaction.</p>
<p>Without the revocation path in the second stage my coins would be lost.</p>

CC BY-SA 4.0
2020-07-27T12:12:06.317Z
2021-09-07T07:54:03.870Z
2021-09-07T07:54:03.870Z
Antoine Poinsot
<p>HTLCs have a different timeout (<code>cltv_expiry</code>) than the regular timeout that we use for penalty transactions (<code>to_self_delay</code>). That is the reason why we use a separate transaction stage (HTLC success/HTLC timeout) to allow our counterparty sufficient time to exercise their right to get the entire balance of the channel in case we broadcast the previous state of the channel.</p>

<p>To elaborate further, when your counterparty tells you to add a HTLC, your version of the commitment transaction will have 3 outputs:</p>

<ol>
<li>Paying to your counterparty immediately</li>
<li>Paying to self, guarded by the revocation key for <code>to_self_delay</code> time</li>
<li>Received HTLC output like below

<pre><code># To remote node with revocation key
OP_DUP OP_HASH160 &lt;RIPEMD160(SHA256(revocationpubkey))&gt; OP_EQUAL
OP_IF
    OP_CHECKSIG
OP_ELSE
    &lt;remote_htlcpubkey&gt; OP_SWAP OP_SIZE 32 OP_EQUAL
    OP_IF
        # To local node via HTLC-success transaction.
        OP_HASH160 &lt;RIPEMD160(payment_hash)&gt; OP_EQUALVERIFY
        2 OP_SWAP &lt;local_htlcpubkey&gt; 2 OP_CHECKMULTISIG
    OP_ELSE
        # To remote node after timeout.
        OP_DROP &lt;cltv_expiry&gt; OP_CHECKLOCKTIMEVERIFY OP_DROP
        OP_CHECKSIG
    OP_ENDIF
OP_ENDIF
</code></pre></li>
</ol>

<p>When you supply the HTLC pre-image to your counterparty the transaction gets resolved. However, even after successful resolution of the HTLC with your counterparty, let us say you decide to cheat them by force closing the earlier state of the commitment transaction containing the HTLC. As soon as you publish this commitment transaction, you publish the HTLC success transaction that consumes the <code>OP_IF</code> part inside the <code>OP_ELSE</code>. Since the HTLC success transaction is consuming an output that is not timelocked, you are not providing enough time for your counterparty to use their right of the revocation key which is in the received HTLC output. That is the reason there is a second stage, where your spending from the offered HTLC output to yourself is locked until <code>to_self_delay</code> which allows your counterparty to use the revocation secret.</p>

<p>Now you might wonder, why the revocation exists in the commitment transaction received HTLC output if it is provided in the HTLC success/timeout transactions. Let us take the above case to explain it. You added the HTLC and signed the commitment transaction. That HTLC was settled by you providing the pre-image to your counterparty and the commitment transaction containing that HTLC was revoked. Despite that, assume you try to broadcast the previous commitment transaction containing the HTLC and refrains from publishing the HTLC success transaction. If revocation did not exist in the commitment transaction, the counterparty might not be able to get their funds back until the <code>cltv_expiry</code> which might extend to hundreds of blocks (couple of days) if there are a number of hops. This is cumbersome since that HTLC was already settled (especially if there are number of previously satisfied HTLCs), and the provision of revocation in the commitment transaction allows the counterparty to settle them immediately. </p>

<p>The revocation part is designed so that your counterparty never suffers because of the actions you decide to take to cheat them. The presence of revocation in commitment transaction and the HTLC success/HTLC timeout transaction help protect the Lightning Network participants from frauds committed their peers.</p>

CC BY-SA 4.0
2019-10-29T10:10:13.040Z
If you publish an **old** commitment tx with 1 received HTLC, the counterparty can enter the timeout process as specified in `cltv_expiry` and then collect the money via HTLC-timeout anyway? So your point is that we don't want the counterparty to wait that long if you cheat? You don't seem to have a good reason to publish this tx though **pure harm** may be wanted.
yyforyongyu
CC BY-SA 4.0
2019-10-29T10:14:45.887Z
@yyforyongyu  (1) Yes, you are correct that the counterparty can collect after the time-out process, but the local node (who is cheating) can spend it immediately using the HTLC success transaction (since it has the pre-image). (2) it is not just pure harm but you are definitely economically incentivized to publish it. You got the funds from your counterparty by providing the pre-image for the HTLC. Suppose after that you provided some funds to your counterparty for some good you bought from them. The previous state that included the HTLC is more beneficial to you so you publish that,.
Ugam Kamat
CC BY-SA 4.0
2019-10-29T10:32:19.667Z
Let's say I'm the local node who is cheating. I have to spend it via a HTLC-success tx, which has a revocation inside it. Once I spend the commitment tx, I have to wait `to_self_delay` time before I can spend the HTLC-success tx, meanwhile, the counterparty can take the money via the revocation?
yyforyongyu
CC BY-SA 4.0
2019-10-29T10:34:13.360Z
@yyforyongyu Yes. Since you can spend the commitment transaction HTLC output immediately (for HTLC success) you will not be providing any time for your counterparty to react. As a result the `to_self_delay` within the HTLC success output allows the counterparty to use the revocation and then spend the money.
Ugam Kamat
CC BY-SA 4.0
2019-10-29T10:43:19.063Z
interesting. This goes back to the original question, if the counterparty can take the money via revocation inside the HTLC-success tx, what's the point of having a revocation inside the commitment tx?
yyforyongyu
CC BY-SA 4.0
2019-10-29T11:08:53.113Z
@yyforyongyu That's answered in the second last paragraph of my answer (i tried to make it more clearer). What if the cheater never publishes the HTLC success transaction? Even though that HTLC is settled, the counterparty might have to wait couple hundred blocks to get it settled (if there are number of hops). Imagine if it contained multiple such HTLCs and you have to wait for each of them to time out despite the fact that all of them have been settled.
Ugam Kamat
CC BY-SA 4.0
2019-10-29T09:45:19.287Z
2019-10-29T11:07:25.513Z
2019-10-29T11:07:25.513Z
Ugam Kamat
<p>The witness script for the output in the HTLC success/timeout transaction is:</p>

<pre><code>OP_IF
    # Penalty transaction
    &lt;revocationpubkey&gt;
OP_ELSE
    `to_self_delay`
    OP_CHECKSEQUENCEVERIFY
    OP_DROP
    &lt;local_delayedpubkey&gt;
OP_ENDIF
OP_CHECKSIG
</code></pre>

<p>Which already exists a penalty transaction. While in the offered HTLC and received HTLC outputs in the commitment transaction, we have,</p>

<pre><code># To remote node with revocation key
OP_DUP OP_HASH160 &lt;RIPEMD160(SHA256(revocationpubkey))&gt; OP_EQUAL
...
</code></pre>

<p>Why don't we put the revocation in the HTLC-Timeout/Success outputs only? </p>

<lightning-network><hash-time-locked-contract>
Why do we need revocation in both the offered/received HTLC outputs and HTLC timeout/success outputs?
yyforyongyu
# Why do we need revocation in both the offered/received HTLC outputs and HTLC timeout/success outputs?

(Asked by: username_0 on 2019-10-29)

The witness script for the output in the HTLC success/timeout transaction is:

```
OP_IF
    # Penalty transaction
    <revocationpubkey>
OP_ELSE
    `to_self_delay`
    OP_CHECKSEQUENCEVERIFY
    OP_DROP
    <local_delayedpubkey>
OP_ENDIF
OP_CHECKSIG

```

Which already exists a penalty transaction. While in the offered HTLC and received HTLC outputs in the commitment transaction, we have,

```
# To remote node with revocation key
OP_DUP OP_HASH160 <RIPEMD160(SHA256(revocationpubkey))> OP_EQUAL
...

```

Why don't we put the revocation in the HTLC-Timeout/Success outputs only?

**Tags:** lightning-network, hash-time-locked-contract


---

## 2 answers

### Answer by username_1 on 2020-07-27. Score: 2

# TL;DR

Because it would create a nasty dependency of the CLTV deltas over the CSV delay or a reduced security for HTLCs.  
Having the revocation path in the second-stage transaction allows to be able to timeout an HTLC (ie your peer cannot redeem it via pre-image anymore) while still leaving the revocation period (CSV) intact for you to be punished if you cheated.

# Two-stage HTLCs

The Lightning Network protocol makes use of two-stage HTLCs.  
*Why*: allow to use absolute timelock delta shorter than the relative timelock delta used for the fundamental security model (punishment), without degrading the security model for HTLC outputs.  
*How*: make (basically) HTLC outputs pay to either the revocation path, the [timeout/success] transactions only broadcastable after block `B`, or the receiver with the preimage. Make the [timeout/success] transaction pay only after full expiration of the revocation period (no preimage path anymore here, if the receiver did not cheat they **will** get paid).

More about two stages HTLCs in [this answer](https://bitcoin.stackexchange.com/a/95543/101498).

# Why put the revocation path at both stages ?

Because the first stage expires at the end of the absolute timelock period, which is likely to be less than the revocation period.  
If the revocation path was not present in the second transaction (which is actually the point of using two stages) then you would either drastically reduce the revocation period for HTLC outputs, or require using insanely high CLTV deltas.

# An example

I've a channel with you, and we agreed on a [`to_self_delay`](https://github.com/lightningnetwork/lightning-rfc/blob/master/02-peer-protocol.md#the-open_channel-message) of 144 blocks (1 day to punish the broadcast of a revoked state) and a (reckless) [`cltv_expiry_delta`](https://github.com/lightningnetwork/lightning-rfc/blob/master/02-peer-protocol.md#cltv_expiry_delta-selection) of 6 blocks.

I just attempted to make a payment through our channel. We appended an [offered HTLC output](https://github.com/lightningnetwork/lightning-rfc/blob/master/03-transactions.md#offered-htlc-outputs) to my commitment transaction and a [received HTLC output](https://github.com/lightningnetwork/lightning-rfc/blob/master/03-transactions.md#received-htlc-outputs) to yours.  
Let's say someone found funny to not take its negligible fees and instead stuck the HTLC to mess with us. After 4 blocks, we fail the HTLC, sign a new pair of commitment transactions and continue operations --I'd later learn that **you** actually stuck the HTLC just after gathering the preimage.

We don't create new states to our channel and the same night I suffer a power outage, my node comes offline and I don't notice it until I'm awake (5 hours later).  
At the exact moment I got offline you took the absolutely irrational decision to broadcast your ancient commitment transaction in which you still have a signed received HTLC output.  
Your transaction gets confirmed, and passed the 6 blocks (still 4 hours until I wake up) you can claim the output with your HTLC success transactions.

4 hours later, I wake up, put my [continuously backed up](https://lightning.readthedocs.io/PLUGINS.html#db-write) node back online and notice the breach.  
Before I could even have the time to feel disillusioned, disappointed and frustrated enough to throw swear words to a [random internet colored alias](https://github.com/lightningnetwork/lightning-rfc/blob/master/07-routing-gossip.md#the-node_announcement-message), my node stole your coins from your commitment transaction's `to_self` output, claimed my `to_remote` output and spent your HTLC success transaction.

Without the revocation path in the second stage my coins would be lost.


---

### Answer by username_2 on 2019-10-29. Score: 2

HTLCs have a different timeout (`cltv_expiry`) than the regular timeout that we use for penalty transactions (`to_self_delay`). That is the reason why we use a separate transaction stage (HTLC success/HTLC timeout) to allow our counterparty sufficient time to exercise their right to get the entire balance of the channel in case we broadcast the previous state of the channel.

To elaborate further, when your counterparty tells you to add a HTLC, your version of the commitment transaction will have 3 outputs:

1. Paying to your counterparty immediately
2. Paying to self, guarded by the revocation key for `to_self_delay` time
3. Received HTLC output like below

   ```
   # To remote node with revocation key
   OP_DUP OP_HASH160 <RIPEMD160(SHA256(revocationpubkey))> OP_EQUAL
   OP_IF
       OP_CHECKSIG
   OP_ELSE
       <remote_htlcpubkey> OP_SWAP OP_SIZE 32 OP_EQUAL
       OP_IF
           # To local node via HTLC-success transaction.
           OP_HASH160 <RIPEMD160(payment_hash)> OP_EQUALVERIFY
           2 OP_SWAP <local_htlcpubkey> 2 OP_CHECKMULTISIG
       OP_ELSE
           # To remote node after timeout.
           OP_DROP <cltv_expiry> OP_CHECKLOCKTIMEVERIFY OP_DROP
           OP_CHECKSIG
       OP_ENDIF
   OP_ENDIF

   ```

When you supply the HTLC pre-image to your counterparty the transaction gets resolved. However, even after successful resolution of the HTLC with your counterparty, let us say you decide to cheat them by force closing the earlier state of the commitment transaction containing the HTLC. As soon as you publish this commitment transaction, you publish the HTLC success transaction that consumes the `OP_IF` part inside the `OP_ELSE`. Since the HTLC success transaction is consuming an output that is not timelocked, you are not providing enough time for your counterparty to use their right of the revocation key which is in the received HTLC output. That is the reason there is a second stage, where your spending from the offered HTLC output to yourself is locked until `to_self_delay` which allows your counterparty to use the revocation secret.

Now you might wonder, why the revocation exists in the commitment transaction received HTLC output if it is provided in the HTLC success/timeout transactions. Let us take the above case to explain it. You added the HTLC and signed the commitment transaction. That HTLC was settled by you providing the pre-image to your counterparty and the commitment transaction containing that HTLC was revoked. Despite that, assume you try to broadcast the previous commitment transaction containing the HTLC and refrains from publishing the HTLC success transaction. If revocation did not exist in the commitment transaction, the counterparty might not be able to get their funds back until the `cltv_expiry` which might extend to hundreds of blocks (couple of days) if there are a number of hops. This is cumbersome since that HTLC was already settled (especially if there are number of previously satisfied HTLCs), and the provision of revocation in the commitment transaction allows the counterparty to settle them immediately.

The revocation part is designed so that your counterparty never suffers because of the actions you decide to take to cheat them. The presence of revocation in commitment transaction and the HTLC success/HTLC timeout transaction help protect the Lightning Network participants from frauds committed their peers.

> **Comments:**
> **username_0**: If you publish an **old** commitment tx with 1 received HTLC, the counterparty can enter the timeout process as specified in `cltv_expiry` and then collect the money via HTLC-timeout anyway? So your point is that we don't want the counterparty to wait that long if you cheat? You don't seem to have a good reason to publish this tx though **pure harm** may be wanted.  
> **username_2**: @username_0  (1) Yes, you are correct that the counterparty can collect after the time-out process, but the local node (who is cheating) can spend it immediately using the HTLC success transaction (since it has the pre-image). (2) it is not just pure harm but you are definitely economically incentivized to publish it. You got the funds from your counterparty by providing the pre-image for the HTLC. Suppose after that you provided some funds to your counterparty for some good you bought from them. The previous state that included the HTLC is more beneficial to you so you publish that,.  
> **username_0**: Let's say I'm the local node who is cheating. I have to spend it via a HTLC-success tx, which has a revocation inside it. Once I spend the commitment tx, I have to wait `to_self_delay` time before I can spend the HTLC-success tx, meanwhile, the counterparty can take the money via the revocation?  
> **username_2**: @username_0 Yes. Since you can spend the commitment transaction HTLC output immediately (for HTLC success) you will not be providing any time for your counterparty to react. As a result the `to_self_delay` within the HTLC success output allows the counterparty to use the revocation and then spend the money.  
> **username_0**: interesting. This goes back to the original question, if the counterparty can take the money via revocation inside the HTLC-success tx, what's the point of having a revocation inside the commitment tx?  
> **username_2**: @username_0 That's answered in the second last paragraph of my answer (i tried to make it more clearer). What if the cheater never publishes the HTLC success transaction? Even though that HTLC is settled, the counterparty might have to wait couple hundred blocks to get it settled (if there are number of hops). Imagine if it contained multiple such HTLCs and you have to wait for each of them to time out despite the fact that all of them have been settled.  

---

