upleb.uk

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

summaryrefslogtreecommitdiff
path: root/src/util.h
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/util.h
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/util.h')
-rw-r--r--src/util.h22
1 files changed, 18 insertions, 4 deletions
diff --git a/src/util.h b/src/util.h
index d72518b..fe605a1 100644
--- a/src/util.h
+++ b/src/util.h
@@ -106,15 +106,29 @@ extern bool fDebug;
106// 2. Burst collapse: repeated LogPrint() calls from the *same source line* 106// 2. Burst collapse: repeated LogPrint() calls from the *same source line*
107// only emit one line per DEDUP_WINDOW_SECS; if more calls land inside 107// only emit one line per DEDUP_WINDOW_SECS; if more calls land inside
108// that window they're counted instead of reprinted, and the count is 108// that window they're counted instead of reprinted, and the count is
109// flushed as a single "(xN similar in Ws)" line the moment the window 109// flushed as a single "(xN similar in Ws)" line once the window expires
110// rolls over. A loop discovering 500 peers by address now produces a 110// -- whether or not that call site ever fires again. A loop discovering
111// small, bounded number of lines instead of 500 -- log growth is capped 111// 500 peers by address now produces a small, bounded number of lines
112// by elapsed time, not by how many similar events happen to fire. 112// instead of 500 -- log growth is capped by elapsed time, not by how
113// many similar events happen to fire.
114//
115// Use LogPrintAlways() instead for anything that reports an irreversible
116// change to money: an obligation voided, a payment sent, a payment that
117// failed. One line standing in for an unknown number of identical events is
118// a tidy report of peer chatter and a false report of a ledger. A reorg
119// voiding 100 entries hits one source line 100 times inside one window;
120// under LogPrint() that read as a single block losing a single 49.49 BTF
121// payment, while 4,950 BTF of obligations were actually destroyed, and the
122// discrepancy was only found by counting entries in pending_payouts.json
123// (issue #3). Bounded log growth is not worth that ambiguity here.
113// --------------------------------------------------------------------------- 124// ---------------------------------------------------------------------------
114bool LogAcceptsCategory(const char* category); 125bool LogAcceptsCategory(const char* category);
115void LogPrintDedup(const char* category, const char* file, int line, const std::string& msg); 126void LogPrintDedup(const char* category, const char* file, int line, const std::string& msg);
127void LogPrintNoCollapse(const char* category, const std::string& msg);
116#define LogPrint(category, ...) \ 128#define LogPrint(category, ...) \
117 do { if (LogAcceptsCategory(category)) LogPrintDedup((category), __FILE__, __LINE__, strprintf(__VA_ARGS__)); } while (0) 129 do { if (LogAcceptsCategory(category)) LogPrintDedup((category), __FILE__, __LINE__, strprintf(__VA_ARGS__)); } while (0)
130#define LogPrintAlways(category, ...) \
131 do { if (LogAcceptsCategory(category)) LogPrintNoCollapse((category), strprintf(__VA_ARGS__)); } while (0)
118 132
119// Every format string in this project goes through one of the four functions 133// Every format string in this project goes through one of the four functions
120// below -- `printf` itself is remapped to OutputDebugStringF just above, and 134// below -- `printf` itself is remapped to OutputDebugStringF just above, and