openingd: fail open_channel at receipt when our dust limit exceeds their reserve - #9479
openingd: fail open_channel at receipt when our dust limit exceeds their reserve#9479Amperstrand wants to merge 1 commit into
Conversation
…eir reserve BOLT ElementsProject#2 requires the accept_channel sender to set dust_limit_satoshis less than or equal to channel_reserve_satoshis from the open_channel message. fundee_channel() quotes this exact MUST in its comment block but implements no check for it: with the chainparams dust limit (546) and an opener reserve below that, CLN replies accept_channel with dust_limit_satoshis=546, violating the sender MUST. Spec-strict peers (e.g. an LDK opener at the 354-sat spec-minimum dust limit) then fail the channel, with nothing above DEBUG on our side recording why. Mirror the existing opener-side check (openingd.c:446-455) in the accepter path, respecting --dev-allowdustreserve like both neighboring checks. The in-suite test sends a true sub-546 reserve by running the opener under --dev-allowdustreserve (a stock fundchannel self-bumps to its dust limit, mirroring test_zeroreserve's construction); it fails on master and passes with this change. Changelog-Fixes: ElementsProject#9439 Fixes: ElementsProject#9439
Andezion
left a comment
There was a problem hiding this comment.
Given dualopend.c (v2 / dual-funding) has no equivalent reserve/dust cross-check at all, and the issue flags that a channel under ~~54,600 sat can hit the same class of problem there (derived 1% reserve below 546) - is a follow-up planned for that path, or is it intentionally left out because the reserve there is derived rather than negotiated?
|
Intentionally left out — the derivation closes it. v2 floors the reserve at |
BOLT #2 requires the accept_channel sender to set
dust_limit_satoshisless than or equal to
channel_reserve_satoshisfrom theopen_channelmessage. CLN's
fundee_channel()quotes this exact MUST in its commentblock but implements no check for it: with the chainparams dust limit
(546) and an opener reserve below that, CLN replies
accept_channelwith
dust_limit_satoshis=546, violating the sender MUST. Aspec-strict opener then fails the channel (the reporter's LDK LSP sits
at the 354-sat floor the spec itself mandates as the minimum dust
limit); nothing above DEBUG on our side records why (#9439).
This adds the mirror of the existing opener-side check (
dust limit … would be above our reserve, openingd.c:446-455) to the accepter path,respecting
--dev-allowdustreservelike both neighboring checks.Notes for reviewers:
an accept_channel whose dust exceeds our reserve) — two unpatched
CLN nodes reject each other in this shape (the opener under
--dev-allowdustreserve; a stockfundchannelself-bumps itsreserve to 546, so the violating open is unreachable without it).
these limits." — but until the bolts change, the MUST stands, and
stock CLN violates it against strict peers today.
docker v26.06 tag with a BOLT8 wire peer: the violation reproduces
at every reserve below 546 I probed (354, 545), clean at 546.
--dev-allowdustreservetosend a true sub-546 reserve (same crutch as
test_zeroreserve); itfails on master and passes with this change.
CLN fails first, at open_channel receipt.
pre-fix wire journal (v26.06.7): accept_channel with dust_limit 546 against opener reserve 354 — expand
post-fix (pr9439): rejection at open_channel receipt + the inclusive 545/546 boundary — expand
Fuller validation record — every cell, the four-version matrix, the red/green transcript, and the repro recipe: https://gist.github.com/Amperstrand/880bf568f792db0227666e9472d2c9b5
Fixes #9439