What changed, and why it matters
This commit simplifies how Electrum stores secret Lightning payment preimages. It removes a code path that let callers leave a privacy flag unset (which previously kept the old value), and instead always defaults to not marking the preimage as public while still preventing a previously public preimage from becoming private. The change is a cleanup, but it slightly alters behavior: callers who used to rely on 'keep the old value' now get 'False' if no old value exists, and any old public mark is preserved. There is no clear security bug in the diff itself, but it touches sensitive secret-handling code.
Review as normal defensive maintenance. Verify that no callers relied on mark_as_public=None to preserve an existing True value, since the new default False combined with OR-preserve-old still protects True→False transitions but changes the explicit API. No immediate patching required unless caller audit reveals a regression.
Security signals we found
Touches preimage storage and privacy flag (is_preimage_public)
Removes explicit exception guarding a state transition
Changes API contract of a sensitive method (Optional[bool] -> bool)
No explicit security context, CVE, or advisory referenced in commit
Evidence from the diff
In LNWallet.save_preimage(), the parameter mark_as_public changed from Optional[bool] (default None) to bool (default False). The old logic looked up the existing DB tuple and, if mark_as_public was None, inherited old_is_public or fell back to False. It also raised an exception if a caller tried to downgrade a public preimage to private. The new code always starts from False, ORs it with old_is_public, and removes the explicit exception. Functionally this still forbids True→False transitions because old_is_public | False remains True, and it removes the None sentinel. The simplification is behaviorally close but not identical: a caller passing mark_as_public=False with no prior record now writes (preimage, False) rather than (preimage, False) anyway, so the observable difference is minimal. The commit does not fix an obvious vulnerability; it is a refactor of preimage privacy-state handling.
Changed components
electrum/lnworker.pyLNWallet.save_preimage()Lightning preimage privacy stateInspect captured patch +3 / −6
diff --git a/electrum/lnworker.py b/electrum/lnworker.py
index 462eaf5..633bf2b 100644
--- a/electrum/lnworker.py
+++ b/electrum/lnworker.py
@@ -2705,17 +2705,14 @@ class LNWallet(Logger):
preimage: bytes,
*,
write_to_disk: bool = True,
- mark_as_public: Optional[bool] = None, # see is_preimage_public
+ mark_as_public: bool = False, # see is_preimage_public
):
assert isinstance(payment_hash, bytes), f"expected bytes, but got {type(payment_hash)}"
assert isinstance(preimage, bytes), f"expected bytes, but got {type(preimage)}"
if sha256(preimage) != payment_hash:
raise Exception("tried to save incorrect preimage for payment_hash")
- old_tuple = _, old_is_public = self._preimages.get(payment_hash.hex(), (None, None))
- if mark_as_public is None: # if unset, keep current DB value
- mark_as_public = old_is_public or False
- if old_is_public and not mark_as_public:
- raise Exception("preimage mark_as_public: True->False transition is forbidden")
+ old_tuple = _, old_is_public = self._preimages.get(payment_hash.hex(), (None, False))
+ mark_as_public |= old_is_public # disallow True->False transition
# sanity checks and conversions done.
new_tuple = preimage.hex(), mark_as_public
if old_tuple == new_tuple: # no change
Why this scored 32/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.