Repository: rotki/rotki

Issue:
There is no way to unset an ethereum node in the settings
## Problem Definition

At the moment if you succesfully set an ethereum node and you want to unset it you can't really do it. The application only accepts another valid ethereum node connection.

## Task

Allow removing an ethereum node connection from the frontend settings.

This should work by adding a check for the empty string right before the attempt connect call here:
https://github.com/rotki/rotki/blob/268bd118f4e4ff3d750e5968694b8b1f8e0b1145/rotkehlchen/chain/ethereum/manager.py#L165

Something like this:

```python
        if endpoint == '':
            if self.web3:
                del self.web3
            self.connected = False
            self.ethrpc_endpoint = ''
```

In the frontend there should be some nice way to send the empty string, rather than simply deleting the endpoint string.


Discussion:

Resolving patch:
diff --git a/rotkehlchen/chain/ethereum/manager.py b/rotkehlchen/chain/ethereum/manager.py
--- a/rotkehlchen/chain/ethereum/manager.py
+++ b/rotkehlchen/chain/ethereum/manager.py
@@ -158,15 +158,23 @@ def is_synchronized(self, current_block: int, latest_block: int) -> Tuple[bool,
     def set_rpc_endpoint(self, endpoint: str) -> Tuple[bool, str]:
         """ Attempts to set the RPC endpoint for the ethereum client.
 
-        Returns a tuple (result, message)
-            - result: Boolean for success or failure of changing the rpc endpoint
-            - message: A message containing information on what happened. Can
-                       be populated both in case of success or failure"""
-        result, message = self.attempt_connect(endpoint)
-        if result:
-            log.info('Setting ETH RPC endpoint', endpoint=endpoint)
-            self.ethrpc_endpoint = endpoint
-        return result, message
+           Returns a tuple (result, message)
+               - result: Boolean for success or failure of changing the rpc endpoint
+               - message: A message containing information on what happened. Can
+                          be populated both in case of success or failure"""
+        if endpoint == '':
+            if self.web3:
+                del self.web3
+                self.web3 = None
+            self.connected = False
+            self.ethrpc_endpoint = ''
+            return True, ''
+        else:
+            result, message = self.attempt_connect(endpoint)
+            if result:
+                log.info('Setting ETH RPC endpoint', endpoint=endpoint)
+                self.ethrpc_endpoint = endpoint
+            return result, message
 
     def query_eth_highest_block(self) -> Optional[int]:
         """ Attempts to query an external service for the block height


Test patch:
diff --git a/rotkehlchen/tests/api/test_settings.py b/rotkehlchen/tests/api/test_settings.py
--- a/rotkehlchen/tests/api/test_settings.py
+++ b/rotkehlchen/tests/api/test_settings.py
@@ -143,6 +143,28 @@ def test_set_rpc_endpoint_fail_not_set_others(rotkehlchen_api_server):
     assert result['eth_rpc_endpoint'] != 'http://working.nodes.com:8545'
 
 
+def test_unset_rpc_endpoint(rotkehlchen_api_server):
+    """Test the rpc endpoint can be unset"""
+    response = requests.get(api_url_for(rotkehlchen_api_server, "settingsresource"))
+    assert_proper_response(response)
+    json_data = response.json()
+    assert json_data['message'] == ''
+    result = json_data['result']
+    assert result['eth_rpc_endpoint'] != ''
+
+    data = {
+        'eth_rpc_endpoint': '',
+    }
+
+    response = requests.put(api_url_for(rotkehlchen_api_server, "settingsresource"), json=data)
+    assert_proper_response(response)
+
+    json_data = response.json()
+    result = json_data['result']
+    assert json_data['message'] == ''
+    assert result['eth_rpc_endpoint'] == ''
+
+
 @pytest.mark.parametrize('added_exchanges', [('kraken',)])
 def test_set_kraken_account_type(rotkehlchen_api_server_with_exchanges):
     server = rotkehlchen_api_server_with_exchanges