XMoveFunds successful rebalances were moving real sats but
reporting nothing to clboss's earnings stats -- they did not show
up in clboss-status, in the fee model, or anywhere else operators
could see them. This wires per-part attribution end-to-end via a
new bus message.
New message:
Boss::Msg::XRebalanceAttribution { source, destination,
amount_moved, fee_spent }
Emission (XMoveFunds):
Inside the existing waitsendpay-success branch, after pushing
the result and accumulating positive-reinforcement feedback for
the middle hops, parse the askrene path for this part:
- source peer = path[0]["node_id_out"] -- the peer we
forwarded to on the first hop, i.e. the far end of the
source channel for this part.
- dest peer = path[last]["node_id_in"] -- the peer that
forwarded back to us on the closing hop (a.k.a. fill_peer).
- amount_moved = waitsendpay.amount_msat (delivered to us).
- fee_spent = amount_sent_msat - amount_msat.
Defensive on malformed JSON: missing fields, non-array path,
or amount_sent < amount_moved all skip the raise rather than
crash the success handler.
An MPP-split clboss-xmovefunds invocation that lands different
parts on different (source, dest) pairs (the common case once
source_scid / dest_scid are sets) gets one attribution per part,
with the actual pair each part used -- finer-grained than
FundsMover's per-Runner attribution.
Subscription (EarningsTracker):
Subscribe alongside the existing Msg::ResponseMoveFunds handler
and run the same symmetric DB update -- source peer gets
in_expenditures += fee and in_rebalanced += amount, destination
peer gets out_expenditures += fee and out_rebalanced += amount.
No pendings lookup: XMoveFunds already identified both peers
before raising, so the new path skips the requester -> Pending
map entirely.
Symmetry sanity check while wiring:
The DEVSTATE/REBALANCER-REDESIGN-2026-05-28.org "Earnings
attribution symmetry" note flagged that the FundsMover path
might debit only one side. Verified against the current code:
response_move_funds already updates both source's in_* and
destination's out_* (EarningsTracker.cpp around lines 430 and
447) -- no fix needed there. The doc concern was correct at
the time but has been resolved since.
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
This commit modifies the schema of EarningsTracker to allow storing
and accessing earning and expenditure data in specific time ranges.
All existing strategies and reports still use all data from all time
so this PR should not change any balancing behavior.
After we've run w/ this for a while we'll have time-based data
collected and can evaluate how to improve the strategies.