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)
```
This commit is contained in:
@@ -69,8 +69,8 @@ class WalletStorage(Logger):
|
||||
except IOError as e:
|
||||
raise StorageReadWriteError(e) from e
|
||||
if self.file_exists():
|
||||
with open(self.path, "r", encoding='utf-8') as f:
|
||||
self.raw = f.read()
|
||||
with open(self.path, "rb") as f:
|
||||
self.raw = f.read().decode("utf-8")
|
||||
self.pos = f.seek(0, os.SEEK_END)
|
||||
self.init_pos = self.pos
|
||||
self._encryption_version = self._init_encryption_version()
|
||||
@@ -86,8 +86,9 @@ class WalletStorage(Logger):
|
||||
def write(self, data: str) -> None:
|
||||
s = self.encrypt_before_writing(data)
|
||||
temp_path = "%s.tmp.%s" % (self.path, os.getpid())
|
||||
with open(temp_path, "w", encoding='utf-8') as f:
|
||||
self.pos = f.write(s)
|
||||
with open(temp_path, "wb") as f:
|
||||
f.write(s.encode("utf-8"))
|
||||
self.pos = f.seek(0, os.SEEK_END)
|
||||
f.flush()
|
||||
os.fsync(f.fileno())
|
||||
try:
|
||||
@@ -105,10 +106,11 @@ class WalletStorage(Logger):
|
||||
def append(self, data: str) -> None:
|
||||
""" append data to file. for the moment, only non-encrypted file"""
|
||||
assert not self.is_encrypted()
|
||||
with open(self.path, "r+", encoding='utf-8') as f:
|
||||
with open(self.path, "rb+") as f:
|
||||
pos = f.seek(0, os.SEEK_END)
|
||||
assert pos == self.pos, (self.pos, pos)
|
||||
self.pos += f.write(data)
|
||||
f.write(data.encode("utf-8"))
|
||||
self.pos = f.seek(0, os.SEEK_END)
|
||||
f.flush()
|
||||
os.fsync(f.fileno())
|
||||
|
||||
|
||||
Reference in New Issue
Block a user