close was issued with unilateraltimeout=180 on a fixed timer,
without regard to the peer's connection state, while one complaint
source (ComplainerByLowConnectRate) selects peers specifically for
a low connect rate. Closing while the peer is offline escalates
to a unilateral force-close after 3 minutes, against exactly the
peers least likely to negotiate a mutual close in time.
Check the peer's channels for a live connection (listpeerchannels
peer_connected) before issuing close, and defer while the peer is
offline. Poll close candidates every 10 minutes rather than once
per solicitation cycle, so a flaky peer's brief online windows are
actually caught. If the peer stays offline for close_patience
(3 days), close anyway and let the short unilateral timeout
escalate; the first-deferred time is persisted in a new
PeerComplaintsDesk_closepending table so restarts do not reset
the patience window. The fees_low gate applies only to that
unilateral path: a mutual close even at high feerates is cheaper
than a unilateral at low feerates, so connected peers are closed
immediately regardless of feerate.
Add tests/boss/test_peercomplaintsdesk_main.cpp covering the close
paths: a connected peer closes immediately; an offline peer defers
and the deferral survives a restart; within patience it holds;
expired patience holds at high fees and closes at low fees;
dropping below the complaint threshold sweeps the deferral;
channel destruction clears it; disabled auto-close closes nothing.
The test drives the module over the bus with a mock CLN on a
socketpair.
Reported by an external security researcher via private disclosure.
Fixes#324
The fee budget check reads out_expenditures, which is only
persisted once a rebalance completes (up to 120 s per run). Each
incoming HTLC spawned an independent rebalance run with no guard,
so concurrent HTLCs to the same underfunded channel each passed
the check against the same stale value, multiplying the intended
25%-of-earnings aggregate cap by the number of concurrent triggers.
Skip HTLC-triggered rebalances for a node that already has one in
flight, mirroring the working guard in EarningsRebalancer. Skipped
HTLCs are released immediately and proceed without JIT rebalancing;
a retry after the in-flight run completes sees both the refilled
channel and the updated budget.
Update the parallel-calls unit test to the new semantics: exactly
one of three concurrent calls is let in, only it requests a
rebalance, and the guard clears once the run completes.
Reported by an external security researcher via private disclosure.
Fixes#323
Introduce `--clboss-max-rebalance-fee-ppm` to cap the fee allowed for a
single rebalance. Both JitRebalancer and EarningsRebalancer register and
use this option, defaulting to 5000 ppm (0.5%). Documentation updated to
explain the new setting.