From d9d5c90b97815db501d9e5fcb474c7ea571264f5 Mon Sep 17 00:00:00 2001 From: Mohil Ahuja Date: Wed, 7 Oct 2026 02:31:44 +0530 Subject: [PATCH] openingd: reject a peer dust_limit_satoshis below 354 sat BOLT 2 requires the receiver of open_channel to fail the channel when dust_limit_satoshis is smaller than 354 satoshis, and accept_channel fields carry the same requirements. We never checked the lower bound, so a peer could open (or accept) a channel with a dust limit as low as 1 sat, making its commitment transactions non-standard. Add the check to check_config_bounds(), which both openingd and dualopend call for open_channel/accept_channel and their v2 forms, so every path is covered. The open_channel fuzz target clamps the dust limit like the other fields it adjusts to get past check_config_bounds(). Fixes: #9403 Changelog-Fixed: Protocol: we now reject channel opens where the peer's `dust_limit_satoshis` is below 354 satoshis, as BOLT 2 requires. --- openingd/common.c | 13 +++++++++++++ tests/fuzz/fuzz-open_channel.c | 3 +++ 2 files changed, 16 insertions(+) diff --git a/openingd/common.c b/openingd/common.c index 7d1ea1844e13..b3c6f5d6297d 100644 --- a/openingd/common.c +++ b/openingd/common.c @@ -165,6 +165,19 @@ bool check_config_bounds(const tal_t *ctx, return false; } + /* BOLT #2: + * + * The receiving node MUST fail the channel if: + *... + * - `dust_limit_satoshis` is smaller than `354 satoshis` (see [BOLT 3](03-transactions.md#dust-limits)). + */ + if (amount_sat_less(remoteconf->dust_limit, AMOUNT_SAT(354))) { + *err_reason = tal_fmt(ctx, + "dust_limit_satoshis %s too small", + fmt_amount_sat(ctx, remoteconf->dust_limit)); + return false; + } + return true; } diff --git a/tests/fuzz/fuzz-open_channel.c b/tests/fuzz/fuzz-open_channel.c index 070a638bf89d..40222bf6c446 100644 --- a/tests/fuzz/fuzz-open_channel.c +++ b/tests/fuzz/fuzz-open_channel.c @@ -397,6 +397,9 @@ static u8 *create_open_channel_msg(const tal_t *ctx, struct state *state) if (to_self_delay > state->max_to_self_delay) to_self_delay = state->max_to_self_delay; + if (amount_sat_less(dust_limit_satoshis, AMOUNT_SAT(354))) + dust_limit_satoshis = AMOUNT_SAT(354); + struct amount_sat total_reserve; if (!amount_sat_add(&total_reserve, channel_reserve_satoshis,