Repository: rotki/rotki

Issue:
Upgrading DB from v26->v27 can fail if user balancer LP events stored in their DB
## Problem Definition

A user who upgraded from v1.16.2 to v1.18.1 notified us that they saw a DB upgrade failure from v26->v27. Which means the app versions v1.17.2 to v1.18.0.

Turns out that for specific user DBs who have had some Balancer LP events detected and had both the balancer events and the balancer pools DB table populated the DB upgrade would fail, since the upgrade deletes the balancer pools table first, hence possibly hitting a constraint.

## Workaround

Workaround is rather easy. Download v1.17.0-v1.17.2, since that can open v26 DB, purge all uniswap and balancer data, and then open with v1.18.XX.

## Task

Fix the upgrade so that this does not occur even for this special case of users.


Discussion:

Resolving patch:
diff --git a/rotkehlchen/db/upgrades/v26_v27.py b/rotkehlchen/db/upgrades/v26_v27.py
--- a/rotkehlchen/db/upgrades/v26_v27.py
+++ b/rotkehlchen/db/upgrades/v26_v27.py
@@ -10,8 +10,6 @@ def upgrade_v26_to_v27(db: 'DBHandler') -> None:
     - Deletes and recreates the tables that were changed after removing UnknownEthereumToken
     """
     cursor = db.conn.cursor()
-    cursor.execute('DROP TABLE IF EXISTS balancer_pools;')
-
     cursor.execute('DROP TABLE IF EXISTS balancer_events;')
     cursor.execute("""
 CREATE TABLE IF NOT EXISTS balancer_events (
@@ -35,6 +33,7 @@ def upgrade_v26_to_v27(db: 'DBHandler') -> None:
     PRIMARY KEY (tx_hash, log_index)
 );
 """)
+    cursor.execute('DROP TABLE IF EXISTS balancer_pools;')
     cursor.execute('DELETE FROM used_query_ranges WHERE name LIKE "balancer_events%";')
 
     cursor.execute('DROP TABLE IF EXISTS amm_swaps;')


Test patch:
diff --git a/rotkehlchen/tests/data/v26_rotkehlchen.db b/rotkehlchen/tests/data/v26_rotkehlchen.db
Binary files a/rotkehlchen/tests/data/v26_rotkehlchen.db and b/rotkehlchen/tests/data/v26_rotkehlchen.db differ
diff --git a/rotkehlchen/tests/db/test_db_upgrades.py b/rotkehlchen/tests/db/test_db_upgrades.py
--- a/rotkehlchen/tests/db/test_db_upgrades.py
+++ b/rotkehlchen/tests/db/test_db_upgrades.py
@@ -2127,6 +2127,9 @@ def test_upgrade_db_26_to_27(user_data_dir):  # pylint: disable=unused-argument
         'SELECT COUNT(*) from used_query_ranges WHERE name LIKE "balancer%";',
     ).fetchone()[0] == 2
     assert cursor.execute('SELECT COUNT(*) from used_query_ranges;').fetchone()[0] == 6
+    assert cursor.execute('SELECT COUNT(*) from amm_swaps;').fetchone()[0] == 2
+    assert cursor.execute('SELECT COUNT(*) from balancer_pools;').fetchone()[0] == 1
+    assert cursor.execute('SELECT COUNT(*) from balancer_events;').fetchone()[0] == 1
 
     # Migrate to v27
     db = _init_db_with_target_version(
@@ -2136,6 +2139,8 @@ def test_upgrade_db_26_to_27(user_data_dir):  # pylint: disable=unused-argument
     )
     cursor = db.conn.cursor()
     assert cursor.execute('SELECT COUNT(*) from used_query_ranges;').fetchone()[0] == 2
+    assert cursor.execute('SELECT COUNT(*) from amm_swaps;').fetchone()[0] == 0
+    assert cursor.execute('SELECT COUNT(*) from balancer_events;').fetchone()[0] == 0
 
     # Finally also make sure that we have updated to the target version
     assert db.get_version() == 27