Repository: rotki/rotki

Issue:
Add/edit/remove ledger action does not get commited to the DB until next commit
## Problem Definition

It's pretty amazing nobody noticed this so far, especially considering users do utilize ledger actions a lot. So both [add](https://github.com/rotki/rotki/blob/b7883aac6070c7cece4ec8ae1b854af24e3cebfd/rotkehlchen/db/ledger_actions.py#L133), [remove](https://github.com/rotki/rotki/blob/b7883aac6070c7cece4ec8ae1b854af24e3cebfd/rotkehlchen/db/ledger_actions.py#L151) and [editing](https://github.com/rotki/rotki/blob/b7883aac6070c7cece4ec8ae1b854af24e3cebfd/rotkehlchen/db/ledger_actions.py#L178) a ledger action does not commit to the DB.

At next commit they are included but ofcourse that can lead to serious problems if you don't commit to the DB soon after or close the application.

## Task

- [x] Write a test for these. Append db checks to the existing checks.
- [x] Fix it. Super simple. Just add a commit to the db in the end of the these functions.


Discussion:

Resolving patch:
diff --git a/rotkehlchen/db/ledger_actions.py b/rotkehlchen/db/ledger_actions.py
--- a/rotkehlchen/db/ledger_actions.py
+++ b/rotkehlchen/db/ledger_actions.py
@@ -131,6 +131,7 @@ def add_ledger_action(
             ),
         )
         identifier = cursor.lastrowid
+        self.db.conn.commit()
         return identifier
 
     def remove_ledger_action(self, identifier: int) -> Optional[str]:
@@ -148,6 +149,7 @@ def remove_ledger_action(self, identifier: int) -> Optional[str]:
                 f'Tried to delete ledger action with identifier {identifier} but '
                 f'it was not found in the DB'
             )
+        self.db.conn.commit()
         return error_msg
 
     def edit_ledger_action(self, action: LedgerAction) -> Optional[str]:
@@ -175,4 +177,5 @@ def edit_ledger_action(self, action: LedgerAction) -> Optional[str]:
                 f'Tried to edit ledger action with identifier {action.identifier} '
                 f'but it was not found in the DB'
             )
+        self.db.conn.commit()
         return error_msg


Test patch:
diff --git a/rotkehlchen/tests/unit/test_ledger_actions.py b/rotkehlchen/tests/unit/test_ledger_actions.py
--- a/rotkehlchen/tests/unit/test_ledger_actions.py
+++ b/rotkehlchen/tests/unit/test_ledger_actions.py
@@ -26,8 +26,12 @@ def test_serialize_deserialize_for_db():
 
 def test_all_action_types_writtable_in_db(database, function_scope_messages_aggregator):
     db = DBLedgerActions(database, function_scope_messages_aggregator)
+
+    query = 'SELECT COUNT(*) FROM ledger_actions WHERE identifier=?'
+    cursor = database.conn.cursor()
+
     for entry in LedgerActionType:
-        db.add_ledger_action(
+        identifier = db.add_ledger_action(
             timestamp=1,
             action_type=entry,
             location=Location.EXTERNAL,
@@ -36,9 +40,76 @@ def test_all_action_types_writtable_in_db(database, function_scope_messages_aggr
             link='',
             notes='',
         )
+        # Check that changes have been committed to db
+        cursor.execute(query, (identifier,))
+        assert cursor.fetchone() == (1,)
     assert len(db.get_ledger_actions(None, None, None)) == len(LedgerActionType)
 
 
+def test_ledger_action_can_be_removed(database, function_scope_messages_aggregator):
+    db = DBLedgerActions(database, function_scope_messages_aggregator)
+
+    query = 'SELECT COUNT(*) FROM ledger_actions WHERE identifier=?'
+    cursor = database.conn.cursor()
+
+    # Add the entry that we want to delete
+    identifier = db.add_ledger_action(
+        timestamp=1,
+        action_type=LedgerActionType.INCOME,
+        location=Location.EXTERNAL,
+        amount=FVal(1),
+        asset=A_ETH,
+        link='',
+        notes='',
+    )
+
+    # Delete ledger action
+    assert db.remove_ledger_action(identifier) is None
+
+    # Check that the change has been committed
+    cursor.execute(query, (identifier,))
+    assert cursor.fetchone() == (0,)
+
+
+def test_ledger_action_can_be_edited(database, function_scope_messages_aggregator):
+    db = DBLedgerActions(database, function_scope_messages_aggregator)
+
+    query = 'SELECT * FROM ledger_actions WHERE identifier=?'
+    cursor = database.conn.cursor()
+
+    # Add the entry that we want to edit
+    identifier = db.add_ledger_action(
+        timestamp=1,
+        action_type=LedgerActionType.INCOME,
+        location=Location.EXTERNAL,
+        amount=FVal(1),
+        asset=A_ETH,
+        link='',
+        notes='',
+    )
+
+    # Data for the new entry
+    new_entry = LedgerAction(
+        identifier=identifier,
+        timestamp=2,
+        action_type=LedgerActionType.GIFT,
+        location=Location.EXTERNAL,
+        amount=FVal(3),
+        asset=A_ETH,
+        link='',
+        notes='updated',
+    )
+
+    assert db.edit_ledger_action(new_entry) is None
+
+    # Check that changes have been committed
+    cursor.execute(query, (identifier,))
+    updated_entry = LedgerAction(*cursor.fetchone())
+    assert updated_entry.timestamp == new_entry.timestamp
+    assert str(updated_entry.amount) == str(new_entry.amount)
+    assert updated_entry.action_type == new_entry.action_type.serialize_for_db()
+
+
 @pytest.mark.parametrize('mocked_price_queries', [prices])
 @pytest.mark.parametrize('db_settings, expected_pnl', [
     ({'taxable_ledger_actions': [