upleb.uk

Public git repos — served from a NIP-34 GRASP relay at git.upleb.uk

summaryrefslogtreecommitdiff
path: root/src/rpc.cpp
diff options
context:
space:
mode:
authorbitflash-maintainer <noreply@bitflash.invalid>2026-09-02 14:14:52 +0000
committerbitflash-maintainer <noreply@bitflash.invalid>2026-09-02 14:14:52 +0000
commit03a69ccfb36861948e11b0871bb9af8f0b280709 (patch)
tree40064bdd36597b7c6486b0efd45efbacc03bc888 /src/rpc.cpp
parente4f898c4a6b9900553c64b9804889b5fdae3e55f (diff)
payout: never collapse a log line that reports money moving
LogPrint()'s burst collapse is right for share and peer chatter and wrong for anything that reports an irreversible change to money. A reorg voided 100 ledger entries totalling 4,950 BTF and the log carried one line, naming one block and 49.49 BTF. The other 99 were counted and never printed, and no "(N similar)" summary appeared either -- a summary was only ever flushed when that same call site fired again, and after the reorg it never did. The missing 4,950 BTF was found by counting entries in pending_payouts.json. Add LogPrintAlways(), which skips the collapse entirely, and move the four payout lines that report money to it: an obligation voided, an obligation dropped, a payment sent, a payment that failed. All four are bursty by nature -- one reorg voids every entry funded by the orphaned block, from a single source line -- which is precisely why one line must not stand in for all of them. Their volume is bounded by how much money moved, which is a number worth the lines. Also sweep expired windows for every call site rather than only the one currently logging, so a burst that stops is still summarised, and report the window's real elapsed time instead of a hardcoded 3s.
Diffstat (limited to 'src/rpc.cpp')
-rw-r--r--src/rpc.cpp10
1 files changed, 6 insertions, 4 deletions
diff --git a/src/rpc.cpp b/src/rpc.cpp
index a4b53ca..2e8f4b8 100644
--- a/src/rpc.cpp
+++ b/src/rpc.cpp
@@ -1732,7 +1732,9 @@ static void FlushMaturePayouts()
1732 } 1732 }
1733 int64 total = 0; 1733 int64 total = 0;
1734 for (auto& kv : it->amounts) total += kv.second; 1734 for (auto& kv : it->amounts) total += kv.second;
1735 LogPrint("payout", "[payout] block %d (%s) was orphaned -- voiding %zu" 1735 // Always: one line per voided entry, never a collapsed summary.
1736 // A reorg voids these in a burst from this one source line.
1737 LogPrintAlways("payout", "[payout] block %d (%s) was orphaned -- voiding %zu"
1736 " payment(s) totalling %s\n", 1738 " payment(s) totalling %s\n",
1737 it->blockHeight, it->blockHash.ToString().substr(0, 14).c_str(), 1739 it->blockHeight, it->blockHash.ToString().substr(0, 14).c_str(),
1738 it->amounts.size(), FormatMoney(total).c_str()); 1740 it->amounts.size(), FormatMoney(total).c_str());
@@ -2036,7 +2038,7 @@ static void PayoutThreadFn(void*)
2036 // funding block can land at any point in that window. Upstream has 2038 // funding block can land at any point in that window. Upstream has
2037 // no equivalent -- it decides once, when the entry matures. 2039 // no equivalent -- it decides once, when the entry matures.
2038 if (!PayoutBlockStillOnChain(r.blockHash)) { 2040 if (!PayoutBlockStillOnChain(r.blockHash)) {
2039 LogPrint("payout", "[payout] block %d (%s) orphaned while queued" 2041 LogPrintAlways("payout", "[payout] block %d (%s) orphaned while queued"
2040 " -- dropping %s to %s\n", 2042 " -- dropping %s to %s\n",
2041 r.blockHeight, r.blockHash.ToString().substr(0, 14).c_str(), 2043 r.blockHeight, r.blockHash.ToString().substr(0, 14).c_str(),
2042 FormatMoney(r.amount).c_str(), r.address.c_str()); 2044 FormatMoney(r.amount).c_str(), r.address.c_str());
@@ -2205,7 +2207,7 @@ static void PayoutThreadFn(void*)
2205 // described by at least one of them at every instant. 2207 // described by at least one of them at every instant.
2206 RecordPayoutTxid(r, wtx.GetHash().GetHex()); 2208 RecordPayoutTxid(r, wtx.GetHash().GetHex());
2207 ForgetPayment(r); 2209 ForgetPayment(r);
2208 LogPrint("payout", "[payout] paid %s to %s (tx %s)\n", 2210 LogPrintAlways("payout", "[payout] paid %s to %s (tx %s)\n",
2209 FormatMoney(r.amount).c_str(), r.address.c_str(), 2211 FormatMoney(r.amount).c_str(), r.address.c_str(),
2210 wtx.GetHash().ToString().substr(0, 12).c_str()); 2212 wtx.GetHash().ToString().substr(0, 12).c_str());
2211 } else { 2213 } else {
@@ -2263,7 +2265,7 @@ static void PayoutThreadFn(void*)
2263 // going away must not turn the log into one line a minute 2265 // going away must not turn the log into one line a minute
2264 // forever, and must not go quiet either. 2266 // forever, and must not go quiet either.
2265 if (r.retries <= 5 || r.retries % 60 == 0) 2267 if (r.retries <= 5 || r.retries % 60 == 0)
2266 LogPrint("payout", "[payout] FAILED to pay %s to %s" 2268 LogPrintAlways("payout", "[payout] FAILED to pay %s to %s"
2267 " (%s spendable, wallet unlocked, block %d on" 2269 " (%s spendable, wallet unlocked, block %d on"
2268 " the main chain) -- attempt %d, retrying in" 2270 " the main chain) -- attempt %d, retrying in"
2269 " 60s; this debt stands until it is paid\n", 2271 " 60s; this debt stands until it is paid\n",