<p>Looking at the <a href="https://github.com/ElementsProject/lightning/blob/a00c357854bffd8add6f2a501110df0e56db6ce8/channeld/full_channel.c#L270" rel="nofollow noreferrer">c-lightning code I find this call</a>: </p>

<pre><code>    txs[0] = commit_tx(ctx, &amp;channel-&gt;funding_txid,
               channel-&gt;funding_txout,
               channel-&gt;funding_msat / 1000,
               channel-&gt;funder,
               channel-&gt;config[!side].to_self_delay,
               &amp;keyset,
               channel-&gt;view[side].feerate_per_kw,
               channel-&gt;config[side].dust_limit_satoshis,
               channel-&gt;view[side].owed_msat[side],
               channel-&gt;view[side].owed_msat[!side],
               committed,
               htlcmap,
               commitment_number ^ channel-&gt;commitment_number_obscurer,
               side);
</code></pre>

<p>in particular the following line: </p>

<pre><code>commitment_number ^ channel-&gt;commitment_number_obscurer
</code></pre>

<p>Tracing down the <code>commitment_number</code> variable this suggests to me that it is really an integer. If you see how often in the code it has to validated that two commitment transactions are directly succeeding each other it makes sense to have an unobscured integer instead of a txid. Consider For example <a href="https://github.com/ElementsProject/lightning/blob/f1a837e091f942ae31be155da71ecf8557d3aa25/channeld/channeld.c#L1022" rel="nofollow noreferrer">this code block</a>:</p>

<pre><code>    /* FIXME: Document this requirement in BOLT 2! */
    /* We can't send two commits in a row. */
    if (peer-&gt;revocations_received != peer-&gt;next_index[REMOTE] - 1) {
        assert(peer-&gt;revocations_received
               == peer-&gt;next_index[REMOTE] - 2);
        peer-&gt;commit_timer_attempts++;
</code></pre>

<p>It is obscured later since the information how many commitment tx existed should not be public. It is as far as I understand obscured with an OTP via XOR. The OTP is the one you mentioned above. The idea is to have an integer that can be used but obscure it when being sent to the blockchain. I did not find a position in the code where the obscured value is taken and processed to a clean value however.</p>

<p>I hope that helps (:</p>

CC BY-SA 4.0
2019-01-30T22:43:04.900Z
Thx for the code lookup Rene. The obscured commitment number is encoded in the commitment transaction for the node, so that during a unilateral close it can quickly lookup which state was broadcast by the counterparty (my understanding), and respond accordingly. Why cant the txid be used as a lookup key (txid->commitment nr)?
James C.
CC BY-SA 4.0
2019-01-30T23:30:17.207Z
for the reasons that I have mentioned it seems more convenient to have an index number for the commitment transactions in memory. If you know it is Commitment Transaction number 100 you can probably derive the revocation key / redeem script via the key derivation instead of storing all that state for every txid.
Rene Pickhardt
CC BY-SA 4.0
2019-01-31T08:21:29.137Z
I don't mean in-memory, but rather why these 48bits help to facilitate a lookup during channel close. I presume a single key represents a lookup key in persistent store to fetch data(sigs) that are required to respond to a revoked close of that state. If this hash-map key were just the unobscured integer, as you suggest, how could this integer be efficiently inferred from the obscured commitment number? (hash-digest). It must be an efficient way for a peer to immediately infer the broadcast state.
James C.
CC BY-SA 4.0
2019-01-31T08:21:32.850Z
For the store lookup (in the implementation), it would make more sense to index by obscured commitment number than state integer as that is what is broadcast. I am open to being mistaken, but I suspect it has something to do with 48bits (obscured key) vs 256bits(TXID)?
James C.
CC BY-SA 4.0
2019-01-30T22:31:51.213Z
2019-01-30T22:31:51.213Z
Rene Pickhardt
<p>The obscured commitment number for each commitment transaction is the lower 48 bits of:</p>

<pre><code>SHA256(payment_basepoint from open_channel || payment_basepoint from accept_channel)
</code></pre>

<p>It is encoded in the lock time and sequence fields (24bits each) of the commitment transaction. I don't understand why it is necessary, the BOLT rfc reads:</p>

<blockquote>
  <p>This obscures the number of commitments made on the channel in the
  case of unilateral close, yet still provides a useful index for both
  nodes (who know the payment_basepoints) to quickly find a revoked
  commitment transaction.</p>
</blockquote>

<p>Why doesn't the TXID of the commitment TX suffice as lookup index key?</p>

<lightning-network><lightning-rfc>
Why is the obscured commitment number necessary in lightning commitment TX's?
James C.
# Why is the obscured commitment number necessary in lightning commitment TX's?

(Asked by: username_0 on 2019-01-30)

The obscured commitment number for each commitment transaction is the lower 48 bits of:

```
SHA256(payment_basepoint from open_channel || payment_basepoint from accept_channel)

```

It is encoded in the lock time and sequence fields (24bits each) of the commitment transaction. I don't understand why it is necessary, the BOLT rfc reads:

> This obscures the number of commitments made on the channel in the
> case of unilateral close, yet still provides a useful index for both
> nodes (who know the payment\_basepoints) to quickly find a revoked
> commitment transaction.

Why doesn't the TXID of the commitment TX suffice as lookup index key?

**Tags:** lightning-network, lightning-rfc


---

## 1 answers

### Answer by username_1 on 2019-01-30. Score: 1

Looking at the [c-lightning code I find this call](https://github.com/ElementsProject/lightning/blob/a00c357854bffd8add6f2a501110df0e56db6ce8/channeld/full_channel.c#L270):

```
    txs[0] = commit_tx(ctx, &channel->funding_txid,
               channel->funding_txout,
               channel->funding_msat / 1000,
               channel->funder,
               channel->config[!side].to_self_delay,
               &keyset,
               channel->view[side].feerate_per_kw,
               channel->config[side].dust_limit_satoshis,
               channel->view[side].owed_msat[side],
               channel->view[side].owed_msat[!side],
               committed,
               htlcmap,
               commitment_number ^ channel->commitment_number_obscurer,
               side);

```

in particular the following line:

```
commitment_number ^ channel->commitment_number_obscurer

```

Tracing down the `commitment_number` variable this suggests to me that it is really an integer. If you see how often in the code it has to validated that two commitment transactions are directly succeeding each other it makes sense to have an unobscured integer instead of a txid. Consider For example [this code block](https://github.com/ElementsProject/lightning/blob/f1a837e091f942ae31be155da71ecf8557d3aa25/channeld/channeld.c#L1022):

```
    /* FIXME: Document this requirement in BOLT 2! */
    /* We can't send two commits in a row. */
    if (peer->revocations_received != peer->next_index[REMOTE] - 1) {
        assert(peer->revocations_received
               == peer->next_index[REMOTE] - 2);
        peer->commit_timer_attempts++;

```

It is obscured later since the information how many commitment tx existed should not be public. It is as far as I understand obscured with an OTP via XOR. The OTP is the one you mentioned above. The idea is to have an integer that can be used but obscure it when being sent to the blockchain. I did not find a position in the code where the obscured value is taken and processed to a clean value however.

I hope that helps (:

> **Comments:**
> **username_0**: Thx for the code lookup username_1. The obscured commitment number is encoded in the commitment transaction for the node, so that during a unilateral close it can quickly lookup which state was broadcast by the counterparty (my understanding), and respond accordingly. Why cant the txid be used as a lookup key (txid->commitment nr)?  
> **username_1**: for the reasons that I have mentioned it seems more convenient to have an index number for the commitment transactions in memory. If you know it is Commitment Transaction number 100 you can probably derive the revocation key / redeem script via the key derivation instead of storing all that state for every txid.  
> **username_0**: I don't mean in-memory, but rather why these 48bits help to facilitate a lookup during channel close. I presume a single key represents a lookup key in persistent store to fetch data(sigs) that are required to respond to a revoked close of that state. If this hash-map key were just the unobscured integer, as you suggest, how could this integer be efficiently inferred from the obscured commitment number? (hash-digest). It must be an efficient way for a peer to immediately infer the broadcast state.  
> **username_0**: For the store lookup (in the implementation), it would make more sense to index by obscured commitment number than state integer as that is what is broadcast. I am open to being mistaken, but I suspect it has something to do with 48bits (obscured key) vs 256bits(TXID)?  

---

