upleb.uk

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

summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbitflash-maintainer <noreply@bitflash.invalid>2026-08-23 11:48:26 +0000
committerbitflash-maintainer <noreply@bitflash.invalid>2026-08-23 11:48:26 +0000
commitc7ada00eeed8ef689b976c7201db2d9c076c17d1 (patch)
treec3abe9a9d71f076c02927fb111fe19d79663e780 /src
parent9e5dc16941ac34e77157d85692d1774d8698b1b4 (diff)
payout: refuse to publish a snapshot that was never stamped
PublishVersioned drops a default-constructed VersionedBlob only by accident. Every serialiser stamps `++gSeq`, so it never produces 0, and 0 then loses the `seq <= publishedSeq` comparison because publishedSeq starts at 0. Both halves of that are incidental. A serialiser written as `seq = gSeq++` -- one character different, and the natural way to write it -- publishes seq 0 for its first snapshot, which would sail past the comparison on a fresh process and write an empty ledger over a real one. There is also a live path that produces an unstamped blob today: FlushMaturePayouts declares `VersionedBlob ledgerSnap` and only fills it if something was voided, then publishes unconditionally. It is harmless for exactly the reasons above, which is to say for no reason that is written down anywhere. One line, checked explicitly, so the guarantee does not depend on how a future serialiser spells its increment. Property: a blob that was never stamped with a version is never written to disk.
Diffstat (limited to 'src')
-rw-r--r--src/rpc.cpp8
1 files changed, 8 insertions, 0 deletions
diff --git a/src/rpc.cpp b/src/rpc.cpp
index 7d7cc8f..c382926 100644
--- a/src/rpc.cpp
+++ b/src/rpc.cpp
@@ -644,6 +644,14 @@ static void PublishVersioned(const std::string& path, const VersionedBlob& v,
644 std::mutex& fileMutex, uint64& publishedSeq, 644 std::mutex& fileMutex, uint64& publishedSeq,
645 const char* what) 645 const char* what)
646{ 646{
647 // A default-constructed blob is not a snapshot of anything; it is a
648 // VersionedBlob nobody filled in. Today they are already dropped, because
649 // every serialiser stamps ++gSeq and so never produces 0, and 0 fails the
650 // seq <= publishedSeq test below -- but only for as long as publishedSeq
651 // starts at 0 and nobody writes `seq = gSeq++`. One character, and the
652 // ledger file becomes "[]". Say it out loud instead of relying on it.
653 if (!v.seq)
654 return;
647 // A file whose loader threw is not a file this process knows the contents 655 // A file whose loader threw is not a file this process knows the contents
648 // of. Writing it would replace a full record of what was owed with 656 // of. Writing it would replace a full record of what was owed with
649 // whatever happened to parse before the error. 657 // whatever happened to parse before the error.