Repository: rotki/rotki

Issue:
Upload data to server died with exception: database plaintext is locked
## Problem Definition

This message popped up 2 times in more than 2 weeks of testing. Since it's just a non-critical error of a task that gets retried later we did not push it but it should be figured out and fixed.

```
Upload data to server died with exception: database plaintext is locked. Check the logs for more details
```

## Logs

This is what is seen in the logs

```
[27/10/2022 23:35:11 CEST] ERROR rotkehlchen.greenlets Greenlet with id 140709858290144: Upload data to server died with exception: database plaintext is locked.
Exception Name: <class 'pysqlcipher3.dbapi2.OperationalError'>
Exception Info: database plaintext is locked
Traceback:
   File "src/gevent/greenlet.py", line 908, in gevent._gevent_cgreenlet.Greenlet.run
  File "rotkehlchen/premium/sync.py", line 142, in maybe_upload_data_to_server
  File "rotkehlchen/data_handler.py", line 198, in compress_and_encrypt_db
  File "rotkehlchen/db/dbhandler.py", line 483, in export_unencrypted
  File "rotkehlchen/db/drivers/gevent.py", line 264, in executescript

[27/10/2022 23:35:11 CEST] ERROR rotkehlchen.user_messages Greenlet with id 140709858290144: Upload data to server died with exception: database plaintext is locked. Check the logs for more details
```


## Task

Fix it


Discussion:
Didn't this happen in the past too? Did we fix it or we could not reproduce?
I saw it at least once. Thought I had fixed it. My self at 01 at night did not remember. We would have to investigate

Resolving patch:
diff --git a/rotkehlchen/data_handler.py b/rotkehlchen/data_handler.py
--- a/rotkehlchen/data_handler.py
+++ b/rotkehlchen/data_handler.py
@@ -193,8 +193,8 @@ def compress_and_encrypt_db(self, password: str) -> Tuple[B64EncodedBytes, str]:
         Returns a b64 encoded binary blob"""
         log.info('Compress and encrypt DB')
         compressor = zlib.compressobj(level=9)
-        with tempfile.TemporaryDirectory() as tmpdirname:
-            tempdb = Path(tmpdirname) / 'temp.db'
+        with tempfile.NamedTemporaryFile(delete=True, suffix='.db') as tempdbfile:
+            tempdb = Path(tempdbfile.name)
             self.db.export_unencrypted(tempdb)
             source_data = bytearray()
             compressed_data = bytearray()
@@ -226,7 +226,6 @@ def decompress_and_decrypt_db(self, password: str, encrypted_data: B64EncodedStr
         - SystemPermissionError if the DB file permissions are not correct
         """
         log.info('Decompress and decrypt DB')
-
         # First make a backup of the DB we are about to replace
         date = timestamp_to_date(ts=ts_now(), formatstr='%Y_%m_%d_%H_%M_%S', treat_as_local=True)
         shutil.copyfile(
diff --git a/rotkehlchen/premium/sync.py b/rotkehlchen/premium/sync.py
--- a/rotkehlchen/premium/sync.py
+++ b/rotkehlchen/premium/sync.py
@@ -133,6 +133,7 @@ def check_if_should_sync(self, force_upload: bool) -> bool:
 
     def maybe_upload_data_to_server(self, force_upload: bool = False) -> bool:
         assert self.premium is not None, 'caller should make sure premium exists'
+        log.debug('Starting maybe_upload_data_to_server')
         with self.data.db.user_write() as cursor:
             try:
                 metadata = self.premium.query_last_data_metadata()
@@ -190,7 +191,6 @@ def maybe_upload_data_to_server(self, force_upload: bool = False) -> bool:
 
     def sync_data(self, action: Literal['upload', 'download']) -> Tuple[bool, str]:
         msg = ''
-
         if action == 'upload':
             if self.check_if_should_sync(force_upload=True) is False:
                 success = False
diff --git a/rotkehlchen/tasks/manager.py b/rotkehlchen/tasks/manager.py
--- a/rotkehlchen/tasks/manager.py
+++ b/rotkehlchen/tasks/manager.py
@@ -141,6 +141,8 @@ def _maybe_schedule_db_upload(self) -> Optional[gevent.Greenlet]:
         assert self.premium_sync_manager is not None, 'caller should make sure premium sync manager exists'  # noqa: E501
         if self.premium_sync_manager.check_if_should_sync(force_upload=False) is False:
             return None
+
+        log.debug('Scheduling task for DB upload to server')
         return self.greenlet_manager.spawn_and_track(
             after_seconds=None,
             task_name='Upload data to server',


Test patch: