Skip to content

Commit

Permalink
improve errorhandling (#491)
Browse files Browse the repository at this point in the history
* imporve errorhandling

* blackify

* better RpcError

* added connection-troubleshooting

* black

* first typo

* Corrections and additions

Co-authored-by: moneymanolis <moneymanolis@protonmail.com>
  • Loading branch information
k9ert and moneymanolis committed Oct 17, 2020
1 parent 75a9d36 commit a718446
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 19 deletions.
77 changes: 77 additions & 0 deletions docs/connect-your-node.md
@@ -0,0 +1,77 @@
# Connect to your node
Specter is a very flexible tool and can be used in a lot of different setups. There are some popular setups which we want to address first. If you want to use Specter with MyNode or Raspiblitz, that might be easy but you might still want to have some guidance. Here is some awesome material to watch and study for MyNode users:

* BTC Sessions [showing](https://www.youtube.com/watch?v=ZQvCncdFMPo) how to start with Specter on Mynode
* Bitcoin-Magazine showing also [some things](https://www.youtube.com/watch?v=ZQvCncdFMPo) MyNode and Specter

If you want to use Specter with a node on your Windows machine:
* Ministry of Nodes [explains](https://www.youtube.com/watch?v=4koKF2MDXtk)

The installation on the Raspiblitz is quite simple as there is an installation option in the ssh-menu. Pretty straightforward, however, we're not aware of any video walkthrough for that. Ping us or make a PR if you're aware of anything for that.

# General thoughts
But let's approach the connection issue more generically. We assume here, that you want to setup everything in your local network. Every computer needs an IP address in your network. So either, Bitcoin Core is running on the same computer as Specter or on two different ones. But both should have private IP addresses - e.g. (most popular) 192.198.X.Y.
For this setup, you don't need to modify your router. Also your Bitcoin Core node doesn't need to be exposed to the internet.

If both are running on the same machine, there are usually a lot less potential network issues. If both are running as the same user, autodetect can be used.

Let's look at all the issues which can potentially occur.

# Potential connection issues

The first thing you should do if it doesn't work out of the box is explicitely configuring the connection to Bitcoin Core. For that, there are the following values to be set:
* Your Bitcoin RPC username is specified in your bitcoin.conf file on the computer where Bitcoin Core is running. If you open the file, it should like this: `rpcuser=bitcoin`
* Your Bitcoin RPC password can also be found in that file. Search for `rpcpassword=aVerySecretPassword`
* Your node's IP address could simply be `http://localhost` if you're running Bitcoin Core on the same machine as Specter. Otherwise, it's, as discussed above, a local network-address starting often enough with 192.168.X.Y.
* Your nodes RPC port (usually 8332)

## Connection failure

`Process finished with code -1Error message: Failed to connect`

This error message can have one of two causes:
1. The IP address is wrong: Double check it
2. The port is wrong (closed) or the service can't be accessed because of other reasons

Checking the IP address is usually easy: Open a command-line and [ping the address](https://www.howtogeek.com/355664/how-to-use-ping-to-test-your-network/). If the computer responds, it might still be the wrong IP but at least you proved that there is an computer existing with that address.

Checking whether the port is open, is a bit more difficult and you might want to do that only if you've went through the hints below. On mainnet, it's usually 8332. If you're on Windows, you can use [one of these tools](https://techtalk.gfi.com/scan-open-ports-in-windows-a-quick-guide/) to check whether the port is open.

Also you should check your bitcoin.conf. There could be several reasons why your service is not available on the port:

### localhost bind-only

The rpc service needs to bind to the right IP address and port. If you're running Specter on the same machine than Core, something like this would be ok:
```
rpcbind=127.0.0.1:8332
```
(You can also specify the rpc port once with rpcport=8332 so you can skip it
with rpcbind etc.)

However, if you're running it on a different machine, you need to make your service available to the outside. That's done by:
* binding it to all network interfaces like `rpcbind=0.0.0.0:8332`
* and also allowing everyone (specifically your machine) to connect to it: `rpcallowip=0.0.0.0/0`

Note: This allow option is only for trouble shooting, ideally you would limit
it to your local subnet or the machine running Specter that wants to talk to the
node via RPC.

### firewall issues

Often enough there are firewalls installed on the machines running services. Usually this is the case if it takes very long until you get a result after clicking the test button in Specter. The solution here is very specific to the firewall used on the server.

"ufw" is a popular and easy to use firewall (Raspiblitz is using it for example).
This is how you open the port:
```
sudo ufw allow 8332
sudo ufw enable
```
Note: Again, ideally, you would restrict the access further after trouble shooting:

```
sudo ufw allow from SPECIFIC IP to any port 8332
```

### Server responded with error code 401:
This issue is due to a wrong password or username configured. Double-check that the values configured match those on the bitcoin.conf

24 changes: 12 additions & 12 deletions src/cryptoadvance/specter/controller.py
Expand Up @@ -546,18 +546,18 @@ def bitcoin_core_settings():
host = arr[1]

if action == "test":
try:
test = app.specter.test_rpc(
user=user,
password=password,
port=port,
host=host,
protocol=protocol,
autodetect=autodetect,
datadir=datadir,
)
except Exception as e:
err = "Fail to connect to the node configured: {}".format(e)
# If this is failing, the test_rpc-method needs improvement
# Don't wrap this into a try/except otherwise the feedback
# of what's wron to the user gets broken
test = app.specter.test_rpc(
user=user,
password=password,
port=port,
host=host,
protocol=protocol,
autodetect=autodetect,
datadir=datadir,
)
elif action == "save":
if current_user.is_admin:
success = app.specter.update_rpc(
Expand Down
6 changes: 3 additions & 3 deletions src/cryptoadvance/specter/rpc.py
Expand Up @@ -184,12 +184,12 @@ class RpcError(Exception):

def __init__(self, message, response):
super(Exception, self).__init__(message)
self.status_code = 500 # default
try:
self.status_code = response.status_code
error = response.json()
except:
# ok already a dict
self.status_code = 500
except Exception as e:
# it's a dict already
error = response
try:
self.error_code = error["error"]["code"]
Expand Down
18 changes: 14 additions & 4 deletions src/cryptoadvance/specter/specter.py
Expand Up @@ -8,6 +8,8 @@
from io import BytesIO
from .helpers import deep_update, clean_psbt
from .rpc import autodetect_rpc_confs, get_default_datadir, RpcError
from urllib3.exceptions import NewConnectionError
from requests.exceptions import ConnectionError
from .rpc import BitcoinRPC
from .device_manager import DeviceManager
from .wallet_manager import WalletManager
Expand Down Expand Up @@ -263,18 +265,26 @@ def test_rpc(self, **kwargs):
r["err"] = ""
r["code"] = 0
except ConnectionError as e:
logger.error(e)
logger.error("Caught an ConnectionError while test_rpc: ", e)

r["tests"]["connectable"] = False
r["err"] = "Failed to connect!"
r["code"] = -1
except RpcError as rpce:
logger.error(rpce)
logger.error("Caught an RpcError while test_rpc: " + str(rpce))
logger.error(rpce.status_code)
r["tests"]["connectable"] = True
if rpce.status_code == 401:
r["tests"]["credentials"] = False
else:
raise rpce
r["code"] = rpc.r.status_code
r["err"] = str(rpce.status_code)
except Exception as e:
logger.error(e)
logger.error(
"Caught an exception of type {} while test_rpc: {}".format(
type(e), str(e)
)
)
r["out"] = ""
if rpc.r is not None and "error" in rpc.r:
r["err"] = rpc.r["error"]
Expand Down

0 comments on commit a718446

Please sign in to comment.