Commit graph

147 commits

Author SHA1 Message Date
Ken Sedgwick
6fe275ad70
JitRebalancer: restore the in-flight guard lost in the #328 squash
The #328 squash commit (986f30d) was created by soft-resetting the
autoclose branch onto origin/master, but the branch's index still held
a tree from before the #327 merge, so the commit silently reverted
Boss/Mod/JitRebalancer.cpp and tests/boss/test_jitrebalancer.cpp to
their pre-guard state.  master and the v0.16.3-rc1 tag therefore lack
the fix for #323 that the CHANGELOG describes.  GitHub's up-to-date
check passed because it checks ancestry, not tree content, and CI
passed because the guard's tests were reverted along with the guard.

Restore both files from the post-#327 master tip (5839241); nothing
else has touched them since, and git diff 5839241 986f30d confirms
the reversion was limited to these two files.

Restores the fix for #323.
2026-08-14 12:33:57 -07:00
Ken Sedgwick
986f30d1b4
PeerComplaintsDesk: defer auto-close while the peer is offline
Some checks failed
Code Base Sanity Check / tests (push) Has been cancelled
Code Base Sanity Check / coverage (push) Has been cancelled
Code Base Sanity Check / build-clang (push) Has been cancelled
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
2026-08-13 13:18:04 -07:00
Ken Sedgwick
16ac283abb
JitRebalancer: skip rebalance if one is already in flight for the destination
Some checks failed
Code Base Sanity Check / tests (push) Has been cancelled
Code Base Sanity Check / coverage (push) Has been cancelled
Code Base Sanity Check / build-clang (push) Has been cancelled
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
2026-08-13 12:05:06 -07:00
Ken Sedgwick
99c0592612
tests/boltz/test_claimtxhandler_scoped_update.cpp: Also cover the apiAccess predicate.
Both inserted rows used the same apiAccess, so the test would not
catch a claim UPDATE scoped by swapId alone.  Add a third row
sharing swapA's swapId under a different apiAccess; the
single-stamped-row count assertion now fails if either predicate
is dropped.  Verified: a swapId-only variant fails the count
assertion.

Prompted by review on #326.
2026-08-12 14:55:09 -07:00
Ken Sedgwick
9075ee32fc
Boltz/Detail/ClaimTxHandler.cpp: Scope claim db update to the claimed swap.
After broadcasting a reverse-swap claim transaction, the handler
recorded the claim with an UPDATE that had no WHERE clause, marking
every row in BoltzServiceFactory_rsub lockedUp=1.  Any other in-flight
swap then took the "Already broadcasted claim tx." early exit and
never broadcast its own claim; its off-chain payment stayed unsettled
until the timeout/refund path unwound it.

Add the same apiAccess + swapId predicates used by the neighboring
SELECTs and DELETE, and a regression test that seeds two swaps,
claims one, and asserts the sibling row is untouched.  The test
fails before this change and passes after.

Reported by Vincenzo Palazzo (Bitcoin Security Council / Sentinel).

Fixes #325.
2026-08-12 13:25:31 -07:00
Ken Sedgwick
157ec0e935
ChannelCreateDestroyMonitor: tolerate missing old_state (CLN v26.06)
CLN's channel_state_changed notification used to emit the sentinel
value "unknown" for old_state when there was no previous state.
That value was deprecated in v25.05 and is last-supported in v26.04;
as of v26.06 the old_state field is simply omitted instead (see
doc/developers-guide/deprecated-features.md, entry
"channel_state_changed.old_state.unknown").

The notification handler unconditionally extracted old_state, which
throws Jsmn::TypeError when the field is absent.  The throw was
caught by the surrounding handler, logged as Error
("Unexpected channel_state_changed payload: ..."), and then the
handler returned without taking action.  Functional behavior was
unchanged compared to the legacy "unknown" path (both result in
no destruction event), but the new release variant produced noisy
Error log lines for every state-changed notification on nodes
running v26.06+.

Add an explicit has() check and leave old_state as the default
empty string when absent.  The empty string will not match either
"CHANNELD_NORMAL" or "CHANNELD_AWAITING_LOCKIN", so the handler
falls through to the no-op return -- the same outcome the legacy
catch-and-log path produced, but silently.

This is the third and final commit of the v26.06 compatibility
PR (preceded by the Dowser and Matchmaker/ActiveProber commits).
2026-08-06 16:41:57 -07:00
Ken Sedgwick
75d4fd36b0
Add test cases for DNS seed parser crash on SOA records (#309)
Add SOA-only and mixed SRV/SOA test inputs to test_parse_dig_srv to reproduce
the crash from issue #309. Both tests currently fail as expected —
parse_dig_srv() passes SOA record fields to decode_bech32_node() which throws
"Not a bech32 string: 3600".
2026-03-23 11:06:27 -07:00
clboss-contributor
4057154967 feat: add clang C++20 build job to CI
Add clang build configuration to catch C++20 compatibility issues early.

Changes:
- Add build-clang job to .github/workflows/build.yml
- Add missing #include<cstdint> for std::uint* types (clang strict mode)
- Add -lexecinfo for FreeBSD in configure.ac (backtrace_symbols)
- Fix pessimizing-move warning in test_earningsrebalancer.cpp
- Fix CHANGELOG.md formatting

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-04 11:24:31 -08:00
Ken Sedgwick
c4be10d63b
feemon: add clboss-feemon-peers to determine peer set for time window 2026-02-27 14:28:59 -08:00
Ken Sedgwick
c58037715c
feemon: add price theory center price 2026-02-27 14:28:55 -08:00
Ken Sedgwick
88c6fd57c4
coroutine: mitigate GCC PR 107288 coroutine issue 2026-02-27 14:28:53 -08:00
Ken Sedgwick
ed16c670bc
feemon: add fee monitor to save per-channel stats
- add clboss-feemon-history command
- add unit tests
2026-02-27 14:28:53 -08:00
Ken Sedgwick
5cad5863fa
add a unit test for listconfigs format handling to prevent regression 2026-02-19 14:47:32 -08:00
Ken Sedgwick
d23778fc6a
fix: make the argument to decode "string" instead of "bolt11" 2026-02-17 15:49:04 -08:00
Ken Sedgwick
b7251de364
fix: use CLN decode RPC in InvoicePayer, add unit test 2026-02-13 11:40:15 -08:00
Ken Sedgwick
cd2fadf80a
add "all" (by_node) mode to clboss-earnings-history API 2026-01-22 11:09:08 -08:00
Ken Sedgwick
54347e4895
tests: Cover more paths to try_schedule_cleanup 2026-01-21 11:40:43 -08:00
Ken Sedgwick
b5e3d52d32
tests: Add test for coroutine frame leak when Ev::Io is never "attached" (never run) 2026-01-21 11:40:42 -08:00
Ken Sedgwick
699565168a
add test_coroutine_cleanup to expose cleanup bug 2026-01-21 11:40:36 -08:00
Ken Sedgwick
14299a23e9 Expose min_nodes_to_process as a configurable option 2025-09-11 13:49:22 -07:00
Ken Sedgwick
1a0008458f Add clboss-feerates RPC
- Register and implement the new clboss-feerates command in OnchainFeeMonitor
    - Document the command in README and note it in the changelog
    - Update RPC manifest tests to include the new command
2025-07-07 11:21:09 -07:00
Ken Sedgwick
9aeb29c541 Add associated primary volume (forwarded and rebalanced) to EarningsTracker
Addresses ([#229])

This allows effective feerates (PPM) to be computed for earnings and
expenses.

This PR updates the schema automatically.  Downgrading to previous
will require manual DB migration (but is possible).  Downgrade
commands are in a comment in EarningsTracker.c
2024-09-25 13:23:04 -05:00
Ken Sedgwick
1bd144a0f8 add clboss-recent-earnings and clboss-earnings-history 2024-09-25 13:23:04 -05:00
Ken Sedgwick
65ce91578e add EarningsTracker::bucket_time quantizer and unit tests 2024-09-25 13:23:04 -05:00
Ken Sedgwick
781c4afb80 add get_now() and mock_get_now() to EarningsTracker and test_earningstracker
A time source is needed for upcoming time buckets change.
2024-09-25 13:23:04 -05:00
Ken Sedgwick
094d99a48a add test_earningstracker for legacy tracking 2024-09-25 13:23:04 -05:00
Ken Sedgwick
b8fb5523ca add Jsmn::Object::operator==
This makes it easier to write test cases by comparing to expected values
2024-09-25 13:23:04 -05:00
Ken Sedgwick
d20acda660 factor parse_json into Jsmn::Object static method
This makes it easier to generate test cases by using literal JSON.
2024-09-25 13:23:04 -05:00
Ken Sedgwick
103201ebd6 tests: Increase jsmn/test_performance timeout 2024-08-22 09:56:56 -07:00
Ken Sedgwick
a36d119ba4 Restore ForwardFeeMonitor's ability to see forwarding fees
Fixes ([#222])

Prior to ElementsProject/lightning@780f32d (`v23.05`) both `fee` and
`fee_msat` were sent for compatibility.  The ForwardFeeMonitor was
checking for the presence of the `fee` field before processing the
record.  This needed to be updated to `fee_msat`.
2024-08-08 13:42:52 -07:00
Ken Sedgwick
eab672dc16 Improve Initialization of OnchainFeeMonitor with Conservative Synthetic History
Previously, CLBOSS initialized the OnchainFeeMonitor with 2 weeks of
synthetic data collected at an arbitrary time on an unknown
system. This historical data often failed to accurately determine
low/high fee conditions until 2 weeks had passed.

This update changes the initialization to use a smaller amount of
deliberately conservative history. This approach discourages CLBOSS
from prematurely declaring a low-fee environment, while still allowing
it to recognize low fees after a few days.

The new size is designed to have 50% influence on the lower 20th
percentile after 24 hours (24 * 6 * 20% * 0.5 = 14.4). This influence
decreases over time: to 25% after two days, 10% after five days, and
continues to decay until it has no effect after two weeks.

It's important to note that CLBOSS will still function in high fee
environments to manage initial liquidity, so this change does not
impact its ability to operate effectively.
2024-07-16 16:02:32 -07:00
Ken Sedgwick
0bd255ce1b Convert ListpeerResult to use ConstructedListpeers
Construct a "compatibility struct" to convert `listpeerchannels`
output into legacy `listpeers` format.

Tests written using the legacy listpeers format can use the
`convert_legacy_listpeers` utility to construct a compatibility
struct.

The test_peerjudge_datagatherer malformed test needed to be malformed
differently to achieve the desired effect.
2024-06-02 16:19:56 -07:00
Ken Sedgwick
2c7ce2f5b9 remove references to the "private" field of listpeers channel info
Fixes issue ([#193])

Changelog-Fixed: Removed references to deprecated "private" field of channel info returned from API.
2024-04-16 16:37:27 -07:00
Lakshya Singh
33292b5d3e gcc: Fix Compatibility Issue with GCC 13
This commit addresses a compatibility issue introduced by GCC
in version 13 (refer to [1]). The issue is present in both
the Arch base system and the latest version of Fedora.

To resolve this, the commit introduces a Kernel-mimicking approach
through a new `Compiler.hpp` file. In this file, we define various
compiler hacks required to enhance code readability by reducing verbosity.

For more details on the issue, see [1]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107134

```
In file included from ./Boss/Msg/RequestPeerFromScid.hpp:4,
                 from Boss/Mod/PeerFromScidMapper.cpp:3:
./Ln/Scid.hpp:16:14: error: 'uint64_t' in namespace 'std' does not name a type; did you mean 'wint_t'?
   16 |         std::uint64_t val;
      |              ^~~~~~~~
      |              wint_t
./Ln/Scid.hpp: In constructor 'Ln::Scid::Scid(std::nullptr_t)':
./Ln/Scid.hpp:19:44: error: class 'Ln::Scid' does not have any field named 'val'
   19 |         Scid(std::nullptr_t _ = nullptr) : val(0) { }
      |                                            ^~~
./Ln/Scid.hpp: In member function 'Ln::Scid::operator bool() const':
./Ln/Scid.hpp:25:24: error: 'val' was not declared in this scope
   25 |                 return val != 0;
      |                        ^~~
./Ln/Scid.hpp: In member function 'bool Ln::Scid::operator==(const Ln::Scid&) const':
./Ln/Scid.hpp:32:24: error: 'val' was not declared in this scope
   32 |                 return val == i.val;
      |                        ^~~
./Ln/Scid.hpp:32:33: error: 'const class Ln::Scid' has no member named 'val'
   32 |                 return val == i.val;
      |                                 ^~~
./Ln/Scid.hpp: In member function 'bool Ln::Scid::operator<(const Ln::Scid&) const':
./Ln/Scid.hpp:39:24: error: 'val' was not declared in this scope
   39 |                 return val < i.val;
      |                        ^~~
./Ln/Scid.hpp:39:32: error: 'const class Ln::Scid' has no member named 'val'
   39 |                 return val < i.val;
      |                                ^~~
/bin/sh ./libtool  --tag=CXX   --mode=compile g++ -DHAVE_CONFIG_H -I.  -I./external/basicsecure/ -I./external/bitcoin-ripemd160/ -I./external/bitcoin-sha256/ -I./external/secp256k1/include/ -I./external/jsmn  -Wall -Werror -pthread    -Wno-noexcept-type -DUSE_VALGRIND -O2 -MT Boss/Mod/libclboss_la-UnmanagedManager.lo -MD -MP -MF Boss/Mod/.deps/libclboss_la-UnmanagedManager.Tpo -c -o Boss/Mod/libclboss_la-UnmanagedManager.lo `test -f 'Boss/Mod/UnmanagedManager.cpp' || echo './'`Boss/Mod/UnmanagedManager.cpp
libtool: compile:  g++ -DHAVE_CONFIG_H -I. -I./external/basicsecure/ -I./external/bitcoin-ripemd160/ -I./external/bitcoin-sha256/ -I./external/secp256k1/include/ -I./external/jsmn -Wall -Werror -pthread -Wno-noexcept-type -DUSE_VALGRIND -O2 -MT Boss/Mod/libclboss_la-UnmanagedManager.lo -MD -MP -MF Boss/Mod/.deps/libclboss_la-UnmanagedManager.Tpo -c Boss/Mod/UnmanagedManager.cpp -o Boss/Mod/libclboss_la-UnmanagedManager.o

```

Reported-by: Lakshya Singh <@king-11>
Co-Developed-by: Lakshya Singh <@king-11>

Signed-off-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com>
2023-08-18 12:34:08 -07:00
ZmnSCPxj jxPCSnmZ
b2def4c51e Boss/Msg/ReqRespTraits.hpp: Use a traits class for requests and response. 2023-07-11 20:57:51 +08:00
ZmnSCPxj jxPCSnmZ
6d6e869ba9 Boss/Mod/ForwardFeeMonitor.cpp: Refactor to use Boss::Mod::PeerFromScidMapper. 2023-07-11 20:57:51 +08:00
ZmnSCPxj jxPCSnmZ
7f9a7f8de8 tests/boss/test_forwardfeemonitor.cpp: Add test for Boss::Mod::ForwardFeeMonitor. 2023-07-11 20:57:51 +08:00
ZmnSCPxj jxPCSnmZ
7f1db47af3 Boss/Mod/JitRebalancer.cpp: Use the new PeerFromScidMapper module. 2023-07-11 20:57:51 +08:00
ZmnSCPxj jxPCSnmZ
397e67ad04 tests/boss/test_stringid.cpp: Add test for new support of string IDs in the JSON interface. 2022-11-23 20:10:55 +08:00
ZmnSCPxj jxPCSnmZ
64ca360f65 *: Use Ln::CommandId for command IDs for received commands and hook events. 2022-11-23 00:36:43 +08:00
ZmnSCPxj jxPCSnmZ
4cb0d764dc Ln/CommandId.cpp: Implement a replacement for numeric command IDs. 2022-11-21 17:18:00 +08:00
ZmnSCPxj jxPCSnmZ
731345fc29 Util/Either.hpp: Utility class for type-safe sum types in C++. 2022-11-21 02:20:31 +08:00
ZmnSCPxj jxPCSnmZ
83001c03a4 Ev/yield.cpp: Add a new multiyield version, for use in testing. 2022-05-12 12:29:45 +08:00
ZmnSCPxj jxPCSnmZ
c90d54b560 Boss/Mod/EarningsRebalancer.cpp: Respect unmanagement. 2022-05-11 12:09:13 +00:00
ZmnSCPxj jxPCSnmZ
c8ddb962df Boss/Mod/JitRebalancer.cpp: Respect unmanagement. 2022-05-11 12:09:13 +00:00
ZmnSCPxj jxPCSnmZ
11bb7a6c19 Boss/Mod/InitialRebalancer.cpp: Respect unmanagement. 2022-05-11 12:09:13 +00:00
ZmnSCPxj jxPCSnmZ
57df6e3e35 tests/boss/test_earningsrebalancer.cpp: Add test for Boss::Mod::EarningsRebalancer. 2022-05-11 12:09:13 +00:00
ZmnSCPxj jxPCSnmZ
773872435b Boss/Mod/JitRebalancer.cpp: Make testable via RPC emulation, also write a test. 2022-05-11 12:09:13 +00:00
ZmnSCPxj jxPCSnmZ
e62e450e1d tests/jsmn/test_parser.cpp: Additional tests for JSMN parser. 2022-05-06 00:50:56 +00:00
ZmnSCPxj jxPCSnmZ
9d26d0d17d Jsmn/Detail/DatumIdentifier.hpp: Alternate faster way of identifying end-of-datum. 2022-05-06 00:50:56 +00:00