cryptoadvance / specter-desktop

A desktop GUI for Bitcoin Core optimised to work with hardware wallets
MIT License
803 stars 238 forks source link

Bug: Removing RPC connection results in internal server error #1906

Closed skwp closed 2 years ago

skwp commented 2 years ago

Describe the bug Specter loads with a white Internal Server Error screen on startup

To Reproduce

I believe this has to do with having multiple nodes registered that are all localhost. Trace is attached. There are a few problems here

  1. Specter should capture all exceptions at the high level and show a graceful error screen. There should never be a white Internal server error screen shown.

  2. Investigate the "can only be changed with one another" error log and figure out what's triggering it.

  3. Figure out how Specter can fall back to or remember the active node if multiple nodes are registered and only one is active.

  4. Maybe warn or prevent Specter from registering competing nodes on the same port. I believe something about that is causing this crash.

==> specter.log <==
[2022-01-29 03:42:05,040] ERROR in wallet_manager: Prevented Trying to update wallet_Manager with broken <BitcoinRpc http://nk3k5xahmoev3azjvfuncq5oqz5u3jqrvwsvlq3zj2mtxbcsb5oru4yd.onion:8332>
[2022-01-29 03:42:05,061] INFO in wallet_manager: Specter seems to be disconnected from Bitcoin Core. Skipping wallets update.
[2022-01-31 14:08:00,057] INFO in specter: Specter exit cleanup: Stopping Tor daemon
[2022-01-31 14:08:50,262] INFO in tor_daemon: tor daemon did not terminated in time, killing!
[2022-01-31 14:08:50,310] INFO in specter: Closing Specter after cleanup
[2022-01-31 14:08:50,369] WARNING in specter: Failed to connect to Tor control port. Error: [Errno 61] Connection refused
[2022-01-31 14:08:50,374] ERROR in cli_server: Could not initialize tor-system
[2022-01-31 14:08:50,375] ERROR in node: SOCKSHTTPConnectionPool(host='nk3k5xahmoev3azjvfuncq5oqz5u3jqrvwsvlq3zj2mtxbcsb5oru4yd.onion', port=8332): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.contrib.socks.SOCKSConnection object at 0x10e3c6710>: Failed to establish a new connection: [Errno 61] Connection refused'))
[2022-01-31 14:08:50,426] ERROR in wallet_manager: Prevented Trying to update wallet_Manager with broken <BitcoinRpc http://nk3k5xahmoev3azjvfuncq5oqz5u3jqrvwsvlq3zj2mtxbcsb5oru4yd.onion:8332>
[2022-01-31 14:08:50,427] INFO in wallet_manager: Specter seems to be disconnected from Bitcoin Core. Skipping wallets update.
==> specterApp.log <==
  File "flask/app.py", line 1525, in full_dispatch_request
  File "flask/app.py", line 1391, in handle_user_exception
  File "cryptoadvance/specter/server_endpoints/controller.py", line 103, in server_error
  File "cryptoadvance/specter/specter.py", line 189, in check
  File "cryptoadvance/specter/user.py", line 254, in check
  File "cryptoadvance/specter/user.py", line 271, in check_wallet_manager
  File "cryptoadvance/specter/managers/wallet_manager.py", line 58, in __init__
  File "cryptoadvance/specter/managers/wallet_manager.py", line 72, in update
Exception: Chain (None) and rpc (<BitcoinRpc http://localhost:8332>) can only be changed with one another

2022-09-30T20:34:43.829Z [info] : stderr-SPECTERD: ERROR in node: Server responded with error code 401:
Traceback (most recent call last):
  File "flask/app.py", line 1521, in full_dispatch_request
  File "flask/app.py", line 1861, in preprocess_request
  File "cryptoadvance/specter/server_endpoints/controller.py", line 161, in selfcheck
  File "cryptoadvance/specter/specter.py", line 189, in check
  File "cryptoadvance/specter/user.py", line 254, in check
  File "cryptoadvance/specter/user.py", line 271, in check_wallet_manager
  File "cryptoadvance/specter/managers/wallet_manager.py", line 58, in __init__
  File "cryptoadvance/specter/managers/wallet_manager.py", line 72, in update
Exception: Chain (None) and rpc (<BitcoinRpc http://localhost:8332>) can only be changed with one another

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "flask/app.py", line 2077, in wsgi_app
  File "flask/app.py", line 1525, in full_dispatch_request
  File "flask/app.py", line 1391, in handle_user_exception
  File "cryptoadvance/specter/server_endpoints/controller.py", line 103, in server_error
  File "cryptoadvance/specter/specter.py", line 189, in check
  File "cryptoadvance/specter/user.py", line 254, in check
  File "cryptoadvance/specter/user.py", line 271, in check_wallet_manager
  File "cryptoadvance/specter/managers/wallet_manager.py", line 58, in __init__
  File "cryptoadvance/specter/managers/wallet_manager.py", line 72, in update
Exception: Chain (None) and rpc (<BitcoinRpc http://localhost:8332>) can only be changed with one another

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "cryptoadvance/specter/node.py", line 306, in check_info
  File "cryptoadvance/specter/rpc.py", line 405, in multi
cryptoadvance.specter.rpc.RpcError: Server responded with error code 401:

2022-09-30T20:34:44.096Z [info] : stderr-SPECTERD: INFO in _internal: 127.0.0.1 - - [30/Sep/2022 15:34:44] "GET /?mode=remote HTTP/1.1" 500 -

2022-09-30T20:34:44.099Z [info] : stderr-SPECTERD: ERROR in _internal: Error on request:
Traceback (most recent call last):
  File "/var/folders/j1/vdrqpw596qxfbp301flfgj4h0000gn/T/_MEIAZCMjx/flask/app.py", line 1521, in full_dispatch_request

  File "/var/folders/j1/vdrqpw596qxfbp301flfgj4h0000gn/T/_MEIAZCMjx/flask/app.py", line 1861, in preprocess_request

  File "/var/folders/j1/vdrqpw596qxfbp301flfgj4h0000gn/T/_MEIAZCMjx/cryptoadvance/specter/server_endpoints/controller.py", line 161, in selfcheck

  File "/var/folders/j1/vdrqpw596qxfbp301flfgj4h0000gn/T/_MEIAZCMjx/cryptoadvance/specter/specter.py", line 189, in check

  File "/var/folders/j1/vdrqpw596qxfbp301flfgj4h0000gn/T/_MEIAZCMjx/cryptoadvance/specter/user.py", line 254, in check

  File "/var/folders/j1/vdrqpw596qxfbp301flfgj4h0000gn/T/_MEIAZCMjx/cryptoadvance/specter/user.py", line 271, in check_wallet_manager

  File "/var/folders/j1/vdrqpw596qxfbp301flfgj4h0000gn/T/_MEIAZCMjx/cryptoadvance/specter/managers/wallet_manager.py", line 58, in __init__

  File "/var/folders/j1/vdrqpw596qxfbp301flfgj4h0000gn/T/_MEIAZCMjx/cryptoadvance/specter/managers/wallet_manager.py", line 72, in update

Exception: Chain (None) and rpc (<BitcoinRpc http://localhost:8332>) can only be changed with one another

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/var/folders/j1/vdrqpw596qxfbp301flfgj4h0000gn/T/_MEIAZCMjx/flask/app.py", line 2077, in wsgi_app

  File "/var/folders/j1/vdrqpw596qxfbp301flfgj4h0000gn/T/_MEIAZCMjx/flask/app.py", line 1525, in full_dispatch_request

  File "/var/folders/j1/vdrqpw596qxfbp301flfgj4h0000gn/T/_MEIAZCMjx/flask/app.py", line 1391, in handle_user_exception

  File "/var/folders/j1/vdrqpw596qxfbp301flfgj4h0000gn/T/_MEIAZCMjx/cryptoadvance/specter/server_endpoints/controller.py", line 103, in server_error

  File "/var/folders/j1/vdrqpw596qxfbp301flfgj4h0000gn/T/_MEIAZCMjx/cryptoadvance/specter/specter.py", line 189, in check

  File "/var/folders/j1/vdrqpw596qxfbp301flfgj4h0000gn/T/_MEIAZCMjx/cryptoadvance/specter/user.py", line 254, in check

  File "/var/folders/j1/vdrqpw596qxfbp301flfgj4h0000gn/T/_MEIAZCMjx/cryptoadvance/specter/user.py", line 271, in check_wallet_manager

  File "/var/folders/j1/vdrqpw596qxfbp301flfgj4h0000gn/T/_MEIAZCMjx/cryptoadvance/specter/managers/wallet_manager.py", line 58, in __init__

  File "/var/folders/j1/vdrqpw596qxfbp301flfgj4h0000gn/T/_MEIAZCMjx/cryptoadvance/specter/managers/wallet_manager.py", line 72, in update

Exception: Chain (None) and rpc (<BitcoinRpc http://localhost:8332>) can only be changed with one another

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/var/folders/j1/vdrqpw596qxfbp301flfgj4h0000gn/T/_MEIAZCMjx/werkzeug/serving.py", line 319, in run_wsgi

  File "/var/folders/j1/vdrqpw596qxfbp301flfgj4h0000gn/T/_MEIAZCMjx/werkzeug/serving.py", line 308, in execute

  File "/var/folders/j1/vdrqpw596qxfbp301flfgj4h0000gn/T/_MEIAZCMjx/flask/app.py", line 2095, in __call__

  File "/var/folders/j1/vdrqpw596qxfbp301flfgj4h0000gn/T/_MEIAZCMjx/werkzeug/middleware/proxy_fix.py", line 187, in __call__

  File "/var/folders/j1/vdrqpw596qxfbp301flfgj4h0000gn/T/_MEIAZCMjx/flask/app.py", line 2080, in wsgi_app

  File "/var/folders/j1/vdrqpw596qxfbp301flfgj4h0000gn/T/_MEIAZCMjx/flask/app.py", line 1438, in handle_exception

  File "/var/folders/j1/vdrqpw596qxfbp301flfgj4h0000gn/T/_MEIAZCMjx/cryptoadvance/specter/server_endpoints/controller.py", line 103, in server_error

  File "/var/folders/j1/vdrqpw596qxfbp301flfgj4h0000gn/T/_MEIAZCMjx/cryptoadvance/specter/specter.py", line 189, in check

  File "/var/folders/j1/vdrqpw596qxfbp301flfgj4h0000gn/T/_MEIAZCMjx/cryptoadvance/specter/user.py", line 254, in check

  File "/var/folders/j1/vdrqpw596qxfbp301flfgj4h0000gn/T/_MEIAZCMjx/cryptoadvance/specter/user.py", line 271, in check_wallet_manager

  File "/var/folders/j1/vdrqpw596qxfbp301flfgj4h0000gn/T/_MEIAZCMjx/cryptoadvance/specter/managers/wallet_manager.py", line 58, in __init__

  File "/var/folders/j1/vdrqpw596qxfbp301flfgj4h0000gn/T/_MEIAZCMjx/cryptoadvance/specter/managers/wallet_manager.py", line 72, in update

Exception: Chain (None) and rpc (<BitcoinRpc http://localhost:8332>) can only be changed with one another
moneymanolis commented 2 years ago

I could reproduce the crash leading to the Internal Server Error.

TODO: Test with multiple nodes, disconnect the current one. UPDATE: Could not replicate the error here (tested with one Bitcoin and one Liquid node and with one Bitcoin main net and Bitcoin regtest node).

As for

Maybe warn or prevent Specter from registering competing nodes on the same port.

I checked, bitcoind already throws an error if you want to bind the RPC port twice (using different data dirs). But, a flash informing the user that he is saving a node with the same RPC port twice would definitely not hurt.

moneymanolis commented 2 years ago

@skwp I took the liberty to rename the issue title, I couldn't reproduce the problem with multiple nodes only when having only one node.

moneymanolis commented 2 years ago

Finally narrowed it down further: The internal server error was triggered, if a RPC connection went down and there were no wallets and then hitting "New wallet" button or refresh.