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 <btf01@proton.me>2026-07-28 15:25:02 -0300
committerGitHub <noreply@github.com>2026-07-28 15:25:02 -0300
commite0c00d3e1b3192efde01fba85d0831470a8fb89c (patch)
treebbceae6508535f6ab8b4a111bb2702c7754d6026 /src/rpc.cpp
parent9eb1b6a3633cae6e644ea9f43e34e890c691f937 (diff)
rpc: the payout comment claims a guarantee the code does not provide (#22)
It reads: Save BEFORE moving to exec queue: if we crash between the save and SendMoney, LoadPendingPayouts re-queues them from the exec-queue section of the file. There is no exec-queue section. SavePendingPayouts serialises gPendingPayouts and nothing else, and a matured payout is erased from it and written out before ever reaching the queue, which lives only in memory. Crash in between and those miners are never paid, with no record they were owed anything. Only the comment changes here. The behaviour needs idempotent payment -- record the txid, look for it in the wallet on restart -- because simply persisting the queue and re-running it would double-pay anyone already sent to, which is the worse failure.
Diffstat (limited to 'src/rpc.cpp')
-rw-r--r--src/rpc.cpp14
1 files changed, 12 insertions, 2 deletions
diff --git a/src/rpc.cpp b/src/rpc.cpp
index 3b2dae9..6f81153 100644
--- a/src/rpc.cpp
+++ b/src/rpc.cpp
@@ -341,8 +341,18 @@ static void QueuePayouts(int blockHeight,
341} 341}
342 342
343// Called from event loop: move matured entries to the exec queue (fast). 343// Called from event loop: move matured entries to the exec queue (fast).
344// Save BEFORE moving to exec queue: if we crash between the save and SendMoney, 344// NOT crash-safe, despite the ordering below looking like it is.
345// LoadPendingPayouts re-queues them from the exec-queue section of the file. 345//
346// A matured payout is erased from gPendingPayouts, the file is rewritten
347// without it, and only then does it reach the exec queue -- which lives in
348// memory alone. SavePendingPayouts writes gPendingPayouts and nothing else;
349// there is no exec-queue section of the file to recover from. Die anywhere
350// between the rewrite and SendMoney and those miners are simply never paid,
351// with no record that they were owed anything.
352//
353// Making this safe needs the payment to be idempotent -- record the txid and
354// check the wallet for it on restart -- rather than a reordering, since
355// re-queueing blindly would double-pay whoever was already sent to.
346static void FlushMaturePayouts() 356static void FlushMaturePayouts()
347{ 357{
348 std::vector<PendingPayout> ready; 358 std::vector<PendingPayout> ready;