Files
ObsidianDragon/tests/test_phase4.cpp
DanS 2e6188a36d fix(chat): order-tolerant memo pairing (survives the daemon output shuffle)
The full-node daemon unconditionally shuffles a transaction's shielded outputs
(transaction_builder.cpp ShuffleOutputs, to hide the change position), so the
two 0-value HushChat memo outputs land at random note positions — the header is
NOT guaranteed to precede its payload. The receive parser paired a header only
with the NEXT payload in position order, so a shuffled send failed to pair (the
message was silently lost) ~50%+ of the time.

groupHushChatMemoOutputs now holds an orphan payload (one seen before its header)
and pairs it with the header when it arrives, so header↔payload pair regardless
of on-chain order. A chat tx carries exactly one header + one payload (the harvest
already skips change outputs), so this is unambiguous.

This is the complete fix for the ObsidianDragon ecosystem: full-node and lite both
receive through this one C++ parser, so full-node→full-node and full-node→lite now
work despite the shuffle, with no daemon fork and no lite-backend change. Context:
SilentDragonXLite (which hardcodes payload position==1 and forced the daemon/backend
question) is being replaced by ObsidianDragonLite. Lite send never shuffles.

Tests: shuffled receive (payload-before-header, and change-interspersed) pairs +
decrypts; all existing ordered-input tests unchanged. Verified: Linux + Windows
build, ctest 100%, hygiene clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-06 16:46:57 -05:00

254 KiB