TeachMeBitcoin

To-Local Output (in Alice's commitment transaction)

From TeachMeBitcoin, the free encyclopedia Reading time: 4 min

12. How Lightning Network Uses CSV Extensively

Lightning's Core Problem: Trustless State Channels

The Lightning Network (LN) allows two parties to transact off-chain by locking funds in a shared multisig UTXO (the "channel"). The key challenge is: how can either party safely close the channel and claim their correct balance, even if the other party tries to cheat by broadcasting an old (outdated) channel state?

The answer is CSV. Without CSV, payment channels cannot be trustlessly enforced. CSV is so central to Lightning that it appears in virtually every commitment transaction output.

Lightning Channel Anatomy

A Lightning channel is maintained through a series of commitment transactions — signed but unbroadcast transactions that reflect the current state of the channel. Each commitment transaction has:

  1. To-Local Output: Funds belonging to the party who broadcasts the commitment. Protected by a CSV delay.

  2. To-Remote Output: Funds belonging to the other party. Immediately spendable (no CSV).

  3. HTLC Outputs: In-flight payments, protected by both hash locks and timelocks.

The To-Local Output and CSV

# To-Local Output (in Alice's commitment transaction)
# Alice can spend to herself after csv_delay blocks
# OR Bob can spend immediately if he has the revocation key
# (The revocation key punishes Alice for broadcasting an old state)

to_local_script (witnessScript):
  OP_IF
    # Revocation path: Bob has Alice's revocation secret
    <RevocationPubKey> OP_CHECKSIG
  OP_ELSE
    # Normal path: Alice after CSV delay
    <csv_delay> OP_CHECKSEQUENCEVERIFY OP_DROP
    <AliceDelayedPubKey> OP_CHECKSIG
  OP_ENDIF

# If Alice broadcasts her commitment transaction:
# - Bob has csv_delay blocks to broadcast a penalty transaction
#   using RevocationPubKey (if Alice is cheating with an old state)
# - If Bob doesn't act within csv_delay, Alice sweeps her funds normally

The csv_delay is negotiated when the channel is opened. Typical values range from 144 (≈1 day) to 2016 blocks (≈2 weeks), depending on the implementation and risk tolerance.

HTLC-Timeout and HTLC-Success Transactions

In-flight payments (HTLCs) on Lightning have their own second-level transactions, both of which use CSV:

# HTLC-Timeout transaction (second-level, spends an offered HTLC output):
# Moves funds to a to_local-style output with csv_delay

# HTLC-Success transaction (second-level, spends a received HTLC output):
# Also moves funds to a to_local-style output with csv_delay

# Why? Because even after an HTLC is resolved, we still need the revocation
# window in case Alice cheated.

# Second-level output script:
  OP_IF
    <RevocationPubKey> OP_CHECKSIG
  OP_ELSE
    <csv_delay> OP_CHECKSEQUENCEVERIFY OP_DROP
    <LocalDelayedPubKey> OP_CHECKSIG
  OP_ENDIF

The Revocation Mechanism: Why CSV Is Non-Negotiable

Every time the channel state updates (a payment is made), the old commitment transaction is revoked by exchanging revocation keys. Here's why CSV is essential to this security model:

Timeline for cheating attempt and response:

Block N:   Alice broadcasts OLD commitment transaction (trying to cheat)
           Alice's to-local output has CSV delay of 144 blocks.

Blocks N to N+144:
           Bob's watchtower detects the old commitment transaction in a block.
           Bob (or his watchtower) constructs a "justice transaction":
           - Input 1: to-local output (using RevocationPubKey — Bob has this)
           - Input 2: any HTLCs (also using revocation)
           - Output: all funds → Bob's address (Alice loses everything)

Block N+144:
           If Bob hasn't acted, Alice can now sweep her to-local output.
           But Bob's justice transaction can no longer claim it.

Without CSV, Bob would need to respond instantly (in the same block). The CSV delay gives Bob (or a watchtower) a practical window to detect and penalize cheating.

Anchor Outputs and CSV(1)

Modern Lightning implementations (BOLT 3) use anchor outputs to allow fee bumping of commitment transactions. Anchors use CSV(1) — a relative lock of 1 block:

# Anchor output script:
  <local_funding_pubkey> OP_CHECKSIG
  OP_IFDUP
  OP_NOTIF
    OP_2 OP_CSV
  OP_ENDIF

# The CSV(2) or CSV(1) at the end allows ANYONE to sweep the anchor
# after a short delay if the owner doesn't claim it.
# This prevents anchor UTXO spam accumulation.

Channel Factory and Multi-Party CSV

In proposed channel factories (multi-party Lightning extensions), CSV delays cascade across multiple layers, requiring careful coordination of all participants' CSV parameters to ensure security at every level.

# Simplified channel factory setup
class ChannelFactory:
    def __init__(self, participants, allocation_csv_delay, htlc_csv_delay):
        self.participants = participants
        self.allocation_csv_delay = allocation_csv_delay  # e.g., 288 blocks
        self.htlc_csv_delay = htlc_csv_delay              # e.g., 144 blocks

    def create_factory_script(self):
        # Factory output requires ALL participants to agree
        n = len(self.participants)
        keys = " ".join(p.pubkey for p in self.participants)
        return f"{n} {keys} {n} OP_CHECKMULTISIG"

    def min_cltv_for_htlc(self, hops_away):
        """
        HTLC CLTV expiry must account for all CSV delays along the path.
        Each hop needs at least htlc_csv_delay blocks for safety.
        """
        return hops_away * self.htlc_csv_delay + self.allocation_csv_delay
☕ Help support TeachMeBitcoin

TeachMeBitcoin is an ad-free, open-source educational repository curated by a passionate team of Bitcoin researchers and educators for public benefit. If you found our articles helpful, please consider supporting our hosting and ongoing content updates with a clean donation:

Ethereum: 0x578417C51783663D8A6A811B3544E1f779D39A85
Bitcoin: bc1q77k9e95rn669kpzyjr8ke9w95zhk7pa5s63qzz
Solana: 4ycT2ayqeMucixj3wS8Ay8Tq9NRDYRPKYbj3UGESyQ4J
Address copied to clipboard!