67 Commits

Author SHA1 Message Date
SomberNight 9d13855c99 storage.write: make os_chmod best-effort
closes https://github.com/spesmilo/electrum/issues/8409
closes https://github.com/spesmilo/electrum/pull/8997
2025-09-05 19:51:33 +00:00
SomberNight 85fc95c71b wallet_db: add configvar for partial_writes, disable by default
Adds a new configvar `WALLET_PARTIAL_WRITES` to enable/disable partial writes for the walletDB.
This is a further restriction on top of the existing restrictions,
e.g. wallet files still need to have file encryption disabled for partial writes.
It defaults to off, so even for unencrypted wallets we disable partial writes for now.

This is used as a stopgap measure until we fix the issues found with the partial writes impl
(see https://github.com/spesmilo/electrum/issues/10000).
2025-07-15 14:03:48 +00:00
SomberNight 3e4601c61d base64.b64decode: always set validate=True
Notably verifymessage and decrypt(message) were silently ignoring trailing garbage
or inserted non-base64 characters present in signatures/ciphertext.
(both the CLI commands and in the GUI)
I think it is much cleaner and preferable to treat such signatures/ciphertext as invalid.

In fact I find it surprising that base64.b64decode(validate=False) is the default.
Perhaps we should create a helper function for it that set validate=True and use that.
2025-06-03 18:58:05 +00:00
ThomasV 3721f04ac8 replace electrum/ecc with electrum_ecc package 2024-10-10 15:46:00 +00:00
ThomasV 2f3d89f415 prepare for separation of ecc module:
- move encrypt/sign functions elsewhere
- remove local dependencies in ecc.py, ecc_fast.py (except logging)
2024-06-17 13:05:57 +02:00
SomberNight 7827be17d1 qt wizard: fix offline 2fa wallet creation in some cases
fixes https://github.com/spesmilo/electrum/issues/9037
2024-05-28 15:31:37 +00:00
SomberNight bd9d0ccc33 ecc: refactor/clean-up sign/verify APIs 2024-04-11 15:25:45 +00:00
SomberNight f495511886 safer os.chmod for wallet files and config: set perms before write
Set unix file permissions first, before writing data.
2024-04-08 14:09:00 +00:00
SomberNight c178be74b7 storage: replace assert in append() with named exception
for nicer bug reports

related https://github.com/spesmilo/electrum/issues/8664
2024-01-17 20:20:24 +00:00
SomberNight bfba0dba56 storage: make partial writes pos sanity-check more robust
The return value of f.write and f.seek cannot be compared when using open() in text mode:
```
>>> import os
>>> s = "aá"
>>>
>>> with open("a1", "w", encoding='utf-8') as f:
...   a = f.write(s)
...   pos = f.seek(0, os.SEEK_END)
...   print(a, pos)
...
2 3
>>>
>>> with open("a2", "wb") as f:
...   a = f.write(s.encode('utf-8'))
...   pos = f.seek(0, os.SEEK_END)
...   print(a, pos)
...
3 3
```

Was getting errors on Windows, probably due to `\r\n` vs `\n`?
```
20231010T121334.522573Z |    ERROR | util.CallbackManager | cb errored. event='adb_set_up_to_date'. exc=AssertionError((2471475, 2522998))
Traceback (most recent call last):
  File "...\electrum\electrum\wallet.py", line 497, in on_event_adb_set_up_to_date
    self.save_db()
  File "...\electrum\electrum\wallet.py", line 403, in save_db
    self.db.write()
  File "...\electrum\electrum\json_db.py", line 48, in wrapper
    return func(self, *args, **kwargs)
  File "...\electrum\electrum\json_db.py", line 389, in write
    self._append_pending_changes()
  File "...\electrum\electrum\json_db.py", line 48, in wrapper
    return func(self, *args, **kwargs)
  File "...\electrum\electrum\json_db.py", line 400, in _append_pending_changes
    self.storage.append(s)
  File "...\electrum\electrum\storage.py", line 110, in append
    assert pos == self.pos, (self.pos, pos)
AssertionError: (2471475, 2522998)
```
2023-10-10 14:33:22 +00:00
ThomasV c495445f51 storage: remember file length when writing to file
- make append fail if the actual file length differs
 - consolidate when file length > 2 * last consolidated length
2023-09-24 12:24:21 +02:00
ThomasV 7ca89f56ee partial-writes using jsonpatch
- partial writes are append only.

 - StoredDict objects will append partial writes to the wallet
   file when items are added, replaced, removed.

 - Lists in the wallet file that have not been registered
   as StoredObject are converted to StoredList, which
   overloads append() and remove(). Those methods too will
   append partial writes to the wallet file.

 - Unlike the old jsonpatch branch, this branch does not support
   file encryption. Encrypted files always fully rewritten, even
   if the change before encryption is a partial write.
2023-09-24 12:24:09 +02:00
SomberNight 312f2641e7 don't use bare except
use "except Exception", or if really needed explicitly "except BaseException"
2023-04-24 12:58:01 +00:00
SomberNight 9df5f55a1f password unification: bugfix, now passes test cases
fixes https://github.com/spesmilo/electrum/issues/8259

note that technically this is an API change for
- wallet.check_password
- wallet.update_password
- storage.check_password
2023-03-20 20:07:53 +00:00
avirgovi b5d2b3c512 create chmod aware of XDG_RUNTIME_DIR
closes https://github.com/spesmilo/electrum/pull/7681
related https://github.com/spesmilo/electrum/issues/6334

Co-authored-by: avirgovi <avirgovi@cisco.com>
Co-authored-by: SomberNight <somber.night@protonmail.com>
2022-08-09 19:04:17 +02:00
SomberNight 73ba00d7dd wallet.restore_wallet_from_text: support creating wallet in-memory 2022-08-08 16:34:04 +02:00
SomberNight c463f5e23d password unification refactor: move methods from wallet to daemon
Note in particular that check_password_for_directory was not safe to use while the daemon had wallets loaded,
as the same file would have two corresponding Wallet() instances in memory. This was specifically handled in
the kivy GUI, on the caller side, by stopping-before and reloading-after the wallets; but it was dirty to
have the caller handle this.
2022-07-06 19:57:27 +02:00
SomberNight d86138a1a5 storage: speed up write() by using faster compression setting
Re total runtime of WalletDB.write() and file size on disk,
for a large encrypted wallet, compare:

before (zlib level=6):
file size 16_670 KB
JsonDB.dump 0.5099 sec
zlib.compress 1.3280 sec
ECPubkey.encrypt_message 0.1720 sec

after change (zlib level=1):
file size 17_527 KB
JsonDB.dump 0.5344 sec
zlib.compress 0.5320 sec
ECPubkey.encrypt_message 0.1837 sec
2021-01-06 21:27:10 +01:00
Malcolm Smith 67ae678137 storage/db: use faster JSON encoder settings when wallet is encrypted
The standard json module has an optimized C encoder, but that doesn't
currently support indentation. So if you request indentation, it falls
back on the slower Python encoder.

Readability doesn't matter for encrypted wallets, so this disables
indentation when the wallet is encrypted.

-----

based on https://github.com/Electron-Cash/Electron-Cash/commit/b2399b6a3e3e39ddd82ffc432bb1ca07f2aab454

For a large encrypted wallet, compare:
before change:
JsonDB.dump 1.3153 sec
zlib.compress 1.281 sec
ECPubkey.encrypt_message 0.1744 sec

after change:
JsonDB.dump 0.5059 sec
zlib.compress 1.3120 sec
ECPubkey.encrypt_message 0.1630 sec

Co-authored-by: SomberNight <somber.night@protonmail.com>
2021-01-06 21:14:56 +01:00
SomberNight d3eefefed4 simplify prev 2020-10-07 20:39:00 +02:00
SomberNight 05ebd0f5b2 storage: try to handle user deleting/renaming wallet file while running
related: #4110, #6358
2020-10-07 19:41:22 +02:00
SomberNight 9931df9f25 storage: fix update-password edge-case
fixes #6400
2020-09-11 13:44:06 +02:00
SomberNight 36178df875 sql: test read-write permissions for given path and raise early
maybe fix #6485
2020-08-25 18:18:07 +02:00
SomberNight 08a7925235 wizard.create_storage: state API and abide by it
none of the callers was handling the return None case properly...
2020-04-09 19:45:38 +02:00
ThomasV e1ce3aace7 Separate db from storage
- storage is content-agnostic
 - db and storage are passed to wallet contructor
2020-02-10 17:45:23 +01:00
ThomasV 63963323be storage: take the DB lock when writing to disk. 2020-02-03 17:08:34 +01:00
ThomasV 149cd9598a Separate JsonDB and WalletDB 2020-02-03 12:36:07 +01:00
SomberNight 02baae10d7 kivy: implement opening storage-encrypted wallet files 2019-12-17 18:39:52 +01:00
SomberNight 01fc048484 CLI: properly auto-upgrade storage when needed even if storage-encrypted
previously commands would error if user had an encrypted storage that needed upgrading
2019-12-15 20:12:51 +01:00
SomberNight c9ede07462 wizard: (qt) add dedicated button to create new wallet 2019-12-12 17:54:46 +01:00
SomberNight a05dab2c4d storage: read/write sanity checks
related: #4110
supersedes: #4528
2019-09-10 21:17:15 +02:00
ThomasV 8e4fe051d3 add comment in storage._write 2019-09-10 09:26:07 +02:00
SomberNight a42a773d19 storage: replace STO_EV_* ints with IntEnum 2019-09-04 13:31:49 +02:00
SomberNight 53d189fc7a storage: fix some madness about get_data_ref() and put() interacting badly
previously load_transactions() had to be called before upgrade();
now we reverse this order.

to reproduce/illustrate issue, before this commit:

try running convert_version_17 and convert_version_18
(e.g. see testcase test_upgrade_from_client_2_9_3_old_seeded_with_realistic_history)
and then in qt console:
>> wallet.storage.db.get_data_ref('spent_outpoints') == wallet.storage.db.spent_outpoints
False
>> wallet.storage.db.get_data_ref('verified_tx3') == wallet.storage.db.verified_tx
False
2019-06-06 19:49:06 +02:00
SomberNight fecef91ee0 interface was suppressing storage r/w exceptions 2019-05-21 18:11:49 +02:00
SomberNight 3385a94753 logging: basics 2019-05-02 15:19:03 +02:00
SomberNight 12b98fa251 wizard: fix regression: unencrypted wallets were not getting upgraded
fixes #5177
2019-03-04 17:23:43 +01:00
SomberNight d11481f360 storage: fix path standardisation 2019-03-04 02:48:25 +01:00
SomberNight 2da6692f73 wizard: some fixes
related: #5174
2019-03-04 02:08:23 +01:00
SomberNight 7458461f13 wizard: fix decryption of hw wallet files
see #5174
2019-03-03 17:33:13 +01:00
SomberNight ef8d7e3227 qt wizard: don't consider old version storage to be incomplete 2019-03-01 19:44:20 +01:00
SomberNight 2ad73050b3 wallet: towards restoring previous performance 2019-03-01 17:59:22 +01:00
ThomasV d8c4bf5662 storage: call load_plugins in decrypt 2019-02-28 15:50:37 +01:00
ThomasV 3631c27ed7 fix: load trustedcoin plugin for two-step wallet creation 2019-02-28 13:11:00 +01:00
ThomasV d74f0c0947 storage_db: fix tests, add modified flag to db class 2019-02-28 12:09:36 +01:00
SomberNight 4b36114d0d small fixups 2019-02-28 09:02:58 +01:00
ThomasV 7f2083f667 separate storage and database (JsonDB) 2019-02-28 09:02:58 +01:00
ThomasV d5790ea109 wizard: do not use on storage object during wallet creation 2019-02-28 09:02:58 +01:00
ThomasV b06b8753e6 fix #5088 2019-02-08 12:59:06 +01:00
ThomasV beb9f63274 follow-up prev 2019-02-08 08:27:23 +01:00