Skip to content

Failure to reject absurdly high channel reserves #9475

Description

@NishantBansal2003

BOLT 2 has one required and one suggested check that provide an upper limit on the channel reserve imposed by the counterparty:

  1. The receiving node MUST fail the channel if:
      - both `to_local` and `to_remote` amounts for the initial commitment transaction are less than or equal to `channel_reserve_satoshis`
    
  2. The receiving node MAY fail the channel if:
      - it considers `channel_reserve_satoshis` too large.
    

CLN implements neither.

Impact

CLN will accept a channel reserve larger than its own initial balance, leaving it unable to send anything on the channel until the funder chooses to push more funds to it. For example, CLN accepts the following channel parameters:

funding_satoshis = 100_000
push_msat = 20_000_000
feerate_per_kw = 500
channel_reserve_satoshis = 87_000
channel_type = anchors

The balances on the initial commitment transaction after fees are:

to_local (funder) = 78_778 sat
to_remote (CLN) = 20_000 sat

Both sides are below the reserve, so CLN cannot spend until it has received a further sats, and the funder is under no obligation to ever send it. CLN's balance is still recoverable on-chain by closing the channel.

One thing to note is that CLN does impose the aggregate reserve check on the funding amount:

lightning/openingd/common.c

Lines 126 to 144 in c1551c5

/* If the resulting channel doesn't meet our minimum "effective capacity"
* set by lightningd, don't bother opening it. */
if (amount_msat_greater_sat(min_effective_htlc_capacity,
capacity)) {
struct amount_sat min_effective_htlc_capacity_sat =
amount_msat_to_sat_round_down(min_effective_htlc_capacity);
*err_reason = tal_fmt(ctx,
"channel capacity with funding %s,"
" reserves %s/%s,"
" max_htlc_value_in_flight_msat is %s,"
" channel capacity is %s, which is below %s",
fmt_amount_sat(ctx, funding),
fmt_amount_sat(ctx, remoteconf->channel_reserve),
fmt_amount_sat(ctx, localconf->channel_reserve),
fmt_amount_msat(ctx, remoteconf->max_htlc_value_in_flight),
fmt_amount_sat(ctx, capacity),
fmt_amount_sat(ctx, min_effective_htlc_capacity_sat));
return false;
This rejects cases where aggregate reserve/fee exceeds the channel capacity, but misses cases where the capacity covers the fee and reserve, yet after pushing some amount to the peer, both balances fall below the reserve.

Suggested fix

Add a check for requirement 1 above, as mandated by the spec.

Also add a cap on the channel reserve imposed by the counterparty. For reference, LND caps at 20% of capacity and Eclair caps at 5%.

Discovery

The missing specification check was detected while fuzzing with smite.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions