wallet_db: handle non-existing parent_set_key in v65
What changed, and why it matters
This commit fixes a bug in Electrum's wallet database upgrade code. When opening an older wallet file, the upgrade routine could crash because it expected a database field (parent_set_key) that wasn't always present. The fix makes the upgrade tolerate missing data. This is a reliability fix for wallet migration, not a remote attack vector.
Apply the patch. Users with older wallets that went through version 63 upgrades should update before opening those wallets to avoid migration failure. No immediate remote-exploitation response is needed.
Security signals we found
Crash during wallet database upgrade (DoS against wallet usability)
Missing input validation on legacy data format
Fixes tracked issue #10487
Evidence from the diff
In electrum/wallet_db.py, _convert_version_65 assumed every entry in received_mpp_htlcs had three elements (resolution, htlc_list, parent_set_key). Wallets upgraded through _convert_version_63 only stored two elements, so unpacking three values raised ValueError during database load. The patch checks the tuple length and sets parent_set_key = None when absent, allowing the upgrade to proceed. Two stale debug log strings referencing _convert_version_62 are also corrected to _convert_version_63.
Changed components
electrum/wallet_db.pyWalletDBUpgrader._convert_version_65received_mpp_htlcs storage migrationInspect captured patch +9 / −3
diff --git a/electrum/wallet_db.py b/electrum/wallet_db.py
index 5e6a29d..90f44e3 100644
--- a/electrum/wallet_db.py
+++ b/electrum/wallet_db.py
@@ -1246,11 +1246,11 @@ class WalletDBUpgrader(Logger):
])
if len(new_type_htlcs) == 0:
- self.logger.debug(f"_convert_version_62: dropping mpp set {payment_key=}.")
+ self.logger.debug(f"_convert_version_63: dropping mpp set {payment_key=}.")
del mpp_sets[payment_key]
else:
recv_mpp_status[1] = new_type_htlcs
- self.logger.debug(f"_convert_version_62: migrated mpp set {payment_key=}")
+ self.logger.debug(f"_convert_version_63: migrated mpp set {payment_key=}")
if forwarding_key is not None:
# if the forwarding key is set for the old mpp set it was either a forwarding
# or a swap hold invoice. Assuming users of 4.6.2 don't use forwarding this update
@@ -1306,7 +1306,13 @@ class WalletDBUpgrader(Logger):
mpp_sets = self.data.get('received_mpp_htlcs', {})
new_mpp_sets = {}
for payment_key, mpp_set in mpp_sets.items():
- resolution, htlc_list, parent_set_key = mpp_set
+ if len(mpp_set) == 2:
+ # if the db has received_mpp_htlcs pre version 65 we cannot assume they have parent_set_key
+ # as _convert_version_63 doesn't set it
+ resolution, htlc_list = mpp_set
+ parent_set_key = None
+ else:
+ resolution, htlc_list, parent_set_key = mpp_set
new_htlc_list = []
for htlc_data_tuple in htlc_list:
scid, update_add_htlc, onion = htlc_data_tuple
Why this scored 30/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.