You should have a working node already, let’s take a closer look now.

After reading part 1, you should have a node up and running and be able to perform rudimentary maintenance tasks already. As you now know, a Docker container bundles everything required to run a node in an image and keeps it isolated from the rest of the system. That doesn’t mean you can’t access it or change some its internal settings though.

2019–06–24: I’m currently restructuring this part, so it will change significantly. It’s mostly informational and some of the info will be obsolete after mainnet launch, so it’s safe to ignore it.

If you watched closely when the node started, you might have noticed that it starts listening on port 40408 and creates an IPC endpoint right away.

INFO [01-03|15:34:22.550] UDP listener up                          self=enode://c74c94efb2c959c93d53c27de819998bdd2e5d07f901b91710de7a6857e4be466[email protected][::]:40408
INFO [01-03|15:34:22.551] RLPx listener up                         self=enode://c74c94efb2c959c93d53c27de819998bdd2e5d07f901b91710de7a6857e4be466[email protected][::]:40408
INFO [01-03|15:34:22.557] IPC endpoint opened                      url=/fusion-node/data/efsn.ipc

Let’s talk about that IPC endpoint first. IPC means inter-process communication. That endpoint can be used to communicate with the node, and since it’s in /fusion-node, you can even access it directly because, as mentioned earlier, that is a mapping to your data directory.

~# sudo ls -al /var/lib/fusion/data/
total 16
drwxr-xr-x 4 root root 4096 Jan  3 22:31 .
drwxr-xr-x 4 root root 4096 Jan  3 16:34 ..
drwx------ 4 root root 4096 Jan  3 22:31 efsn
srw------- 1 root root    0 Jan  3 22:31 efsn.ipc
drwxr-xr-x 2 root root 4096 Jan  3 22:31 keystore

There it is. You can’t do much with it right now though, because you need a matching client application to access it. Let’s look for one. Make sure your container is running at this point, or you’ll get the message Error response from daemon: Container … is not running.

~# sudo docker exec -it fusion sh

You’re now inside the container. What you just did was simply to execute the sh binary within the container, which is a shell.

~# ls -al
total 64
drwxr-xr-x    1 root     root          4096 Jan  3 21:30 .
drwxr-xr-x    1 root     root          4096 Jan  3 21:30 ..
-rwxr-xr-x    1 root     root             0 Jan  3 21:30 .dockerenv
drwxr-xr-x    2 root     root          4096 Dec 20 22:25 bin
drwxr-xr-x    5 root     root           340 Jan  3 21:31 dev
lrwxrwxrwx    1 root     root            35 Dec 29 19:42 docker-entrypoint.sh -> /usr/local/bin/docker-entrypoint.sh
drwxr-xr-x    1 root     root          4096 Jan  3 21:30 etc
drwxr-xr-x    4 root     root          4096 Jan  3 15:34 fusion-node
drwxr-xr-x    2 root     root          4096 Dec 20 22:25 home
drwxr-xr-x    1 root     root          4096 Dec 20 22:25 lib
drwxr-xr-x    5 root     root          4096 Dec 20 22:25 media
drwxr-xr-x    2 root     root          4096 Dec 20 22:25 mnt
dr-xr-xr-x  145 root     root             0 Jan  3 21:31 proc
drwx------    1 root     root          4096 Jan  3 21:31 root
drwxr-xr-x    2 root     root          4096 Dec 20 22:25 run
drwxr-xr-x    2 root     root          4096 Dec 20 22:25 sbin
drwxr-xr-x    2 root     root          4096 Dec 20 22:25 srv
dr-xr-xr-x   13 root     root             0 Jan  3 21:31 sys
drwxrwxrwt    2 root     root          4096 Dec 20 22:25 tmp
drwxr-xr-x    1 root     root          4096 Dec 20 22:25 usr
drwxr-xr-x    1 root     root          4096 Dec 20 22:25 var

You’ll notice that the contents of the container generally resemble a normal Linux installation. If you now do ls /fusion-node here, you’ll see the files and directories from your /var/lib/fusion/data directory as expected. For now, you only need the client. You can find here:

~# ls -al /usr/local/bin/
total 38392
drwxr-xr-x    1 root     root          4096 Dec 29 19:42 .
drwxr-xr-x    1 root     root          4096 Dec 20 22:25 ..
-rwxr-xr-x    1 root     root          1912 Dec 28 23:07 docker-entrypoint.sh
-rwxr-xr-x    1 root     root      39297488 Dec 29 19:42 efsn

The docker-entrypoint.sh script is executed when the cointainer is started and does some basic setup before it launches the node itself, efsn.

efsn is based on the go-ethereum implementation, so you can do pretty much everything you could do with geth. For example use it to attach a console. That’s an integrated function of efsn, so it’s the same executable as when starting the node itself. You can do it from within the container while you’re there already:

~# /usr/local/bin/efsn attach ipc:///fusion-node/data/efsn.ipc

Or you can exit (this is a literal command) first to jump out of the container, back to the regular shell, and then do it like this:

~# sudo docker exec -it fusion /usr/local/bin/efsn 
 attach /fusion-node/data/efsn.ipc

That’s nice because it’s only one step instead of two, and you can always find it in your shell history or even create an alias for it.

Note that you could as well use the Websocket or HTTP endpoints to attach to the console:

~# docker exec -it fusion /usr/local/bin/efsn 
 attach ws://127.0.0.1:9001
~# docker exec -it fusion /usr/local/bin/efsn 
 attach http://127.0.0.1:9000

If you watch closely though, you’ll notice that there’s a difference between connecting via IPC or these endpoints: the modules list is different. All modules are available via IPC by default. That’s because if you can access the IPC endpoint, it’s safe to assume that you have full access to the node anyway, so there’s no use in limiting access.

This also works for remote hosts, which is why you should never publish these ports unless you’re running a standalone gateway! And even then you’d have to add additional security measures, because encryption isn’t a component of the node but has to be configure separately, like an nginx proxy. Try this:

~# docker exec -it fusion /usr/local/bin/efsn 
 attach wss://gateway.fusionnetwork.io:10001

You are now directly connected to one of the official gateways (which is using port 10001 instead of 9001); you can enter eth.blockNumber to see the current block that the node is on for example. That is okay for the gateway because it doesn’t do much really, but your own node will start with your unlocked wallet, so you definitely don’t want that exposed to the whole world.

From here you can control the node using the management API. That list is incomplete, but gives a nice overview. Let’s try some commands!

Note: I’ll prepend commands with > instead of ~# when you’re working with the node’s console, so you can differentiate it from the system shell.

> admin.nodeInfo
{
  enode: "enode://c74c94efb2c959c93d53c27de819998bdd2e5d07f901b91710de7a6857e4be466[email protected][::]:40408",
  id: "c74c94efb2c959c93d53c27de819998bdd2e5d07f901b91710de7a6857e4be466d97f9de7cfd5e9e08ce59f2fe6e152f9eb55726bb6ee0e9ab103da567c1543d",
  ip: "::",
  listenAddr: "[::]:40408",
  name: "Efsn/v1.8.16-unstable/linux-amd64/go1.10.7",
  ports: {
    discovery: 40408,
    listener: 40408
  },
  protocols: {
    eth: {
      config: {
        byzantiumBlock: 0,
        chainId: 1,
        daoForkBlock: 0,
        datong: {...},
        eip150Block: 0,
        eip150Hash: "0x0000000000000000000000000000000000000000000000000000000000000000",
        eip155Block: 0,
        eip158Block: 0,
        homesteadBlock: 0
      },
      difficulty: 1694218914,
      genesis: "0x3048d16497f3c67b2a3e01a4e8c1350e1464ef354c18c7c7518b242b9b5a0785",
      head: "0x231d6d080ea7698e39c2e7a04ae9434d06eeb9d660812e7b09196a3bf5656daf",
      network: 1
    }
  }
}

admin.nodeInfo tells you some stuff about your node. You’ll notice the discovery and listener entries, which again hint at port 40408.

Connect to the Fusion console again:

~# sudo docker exec -it fusion /usr/local/bin/efsn 
 attach /fusion-node/data/efsn.ipc

You can show the info of all other nodes you’re connected to:

> admin.peers
[{
    caps: ["eth/62", "eth/63"],
    id: "a98adcb33b9684b8642d902711830f840989bd925d7947df4d76cd66bcdffc01af01062186448a84d5821a493512d82b2fdfd7ae3d8f6e6dd9987e38a345f8cd",
    name: "Efsn/v1.8.16-unstable/linux-amd64/go1.10.7",
    network: {
      inbound: true,
      localAddress: "172.17.0.2:40408",
      remoteAddress: "203.56.113.178:48956",
      static: false,
      trusted: false
    },
    protocols: {
      eth: {
        difficulty: 1695536043,
        head: "0x79aefe62e4f89e96fab60d078b3084e00c838f54ba152c8796b91a96bf3230e2",
        version: 63
      }
    }
}]

This list will probably be much longer for you. If it’s not, that would be suboptimal. The blocks you seal have to be propagated through the network, and your node has to constantly catch up with the network by fetching blocks sealed by others so it can validate them. Low or no peers means you’re not really participating in the consensus.

Now, if your node doesn’t find any others, or constantly drops its connections because of chain issues, you can force it to connect to some other nodes so it uses those to find more nodes. This is documented here, among other things related to network connectivity.

To manually connect to a node, you need its ID, public IP address and the port it’s listening on. If you find someone nice with a well connected and stable node, he might give you that information. The ID and port can be found using

> admin.nodeInfo

Scroll up a bit and you’ll find an example output. The important part here is the enode URL:

enode://c74c94efb2c959c93d53c27de819998bdd2e5d07f901b91710de7a6857e4be466[email protected][::]:40408

The IP address is still missing here, [::] is a placeholder. It’s the address you probably used to connect to your server via SSH, you can usually find it in your provider’s management interface or the order confirmation mail he sent you. It looks like this: 203.56.113.178.
You can also get it with this command, which simply does an HTTPS request to a public API asking for the IP address your request originates from:

~# curl -s https://api.ipify.org

Note that the article linked above says that the “hostname can only be given as an IP address”. efsn was patched to support domains here, but I wouldn’t rely on that.

You can also combine the commands you just used to get the enode URL in one shot, like this for example:

~# docker exec fusion /usr/local/bin/efsn 
 attach /fusion-node/data/efsn.ipc --exec 'admin.nodeInfo.enode' 
 | sed "s/[::]/$(curl -s https://api.ipify.org)/g"

Note that you don’t need Docker’s -it options here because you’re not really interacting with the console this time. You can then add the peer on a different node like this (not a real example, don’t use it):

>admin.addPeer("enode://c74c94efb2c959c93d53c27de819998bdd2e5d07f901b91710de7a6857e4be466[email protected]203.56.113.178:40408")

There is an upper limit of 25 peers (default) you can connect to, unless you’re using a workaround (see below). Note that manually added peers are never dropped completely, unless forcefully removed (see below) or if the node is restarted. So unlike automatically discovered peers, your node will always try to connect to them even if they’re broken or down. For that reason, only add reliable nodes, or you will gain nothing from it and it may even do more harm than good.
The process also isn’t bidirectional, unless you control the other node too (or know the one who does) and add each other mutually, so another node might just deny your connection attempt. This is especially true for trusted peers.

If you’re running multiple nodes yourself, you can try and use the admin.addTrustedPeer command. This isn’t really well documented, but the difference is that peers added via this function are privileged in a way that they will not count towards the limit of 25 peers.

There’s also a way to configure fully static peers, by putting a file called static-nodes.json into Fusion’s data directory:

~# sudo nano /var/lib/fusion/data/static-nodes.json

The peers herein will always be loaded on startup (like bootnodes, see below) so they’re never lost, even between node restarts. The file contains the enode URLs of the peers you want to add in a JSON array:

[
 "enode://[email protected]:port",
 "enode://[email protected]:port",
 "enode://[email protected]:port"
]

Note the comma at the end of each line, except for the last one.

This also works for trusted nodes, simply name the file trusted-nodes.json.
You can also do both. Always think twice before you add peers though, there’s a reason those limits exist!
If you look at admin.peers again, you’ll see that the changes reflect in its output, as these lines should now have changed for some peers, depending on how you configured them:

static: true,
trusted: true

Both entries have been false before, and still are for most peers which have been discovered automatically. That way you can tell them apart.

Unfortunately, none of this is guaranteed to work instantly or at all. There’s some magic involved with node discovery, so there’s no “clumping together” of nodes but a relatively even distribution. You’ll connect to other nodes by certain rules, and those nodes shouldn’t cause errors, or they’ll be dropped again. Also every node you connect to may deny or drop you at any time, so you don’t necessarily see a connection directly using admin.peers. You have to be a bit lucky and patient. If you have 8+ peers, you’re already on the safe side. You might also face new issues by connecting to too many broken or slow nodes, so again, be reasonable here.

You can find a list of official nodes here. You don’t have to add them manually (and you never should), they’re hardcoded into efsn and will be used when your node starts (so called bootnodes), so it always finds some peers as a starting point for node discovery.

You can automatically generate a list of enode URLs for all currently active peers you initiated an outbound connection with (meaning you found them via peer discovery), excluding those already in your static and/or trusted peers list, from the shell like this for example:

~# docker exec fusion /usr/local/bin/efsn attach /fusion-node/data/efsn.ipc --exec "admin.peers.filter(function(peer){return(peer.network.inbound==false&&peer.network.static==false&&peer.network.trusted==false)}).map(function(peer){return 'enode://'+peer.id+'@'+peer.network.remoteAddress})"|sed 's/, /,n/g'|sed 's/[/[n/;s/]/n]/'

This might be helpful for “node harvesting”, i.e. keeping a list of “good” peers. Don’t instantly add everything appearing here to your static/trusted peers though, you should check that you’ve been connected to it for some time already, as “fresh” nodes will appear here too for a few seconds before you drop them because of an error.

You can remove peers as well, using the ID that admin.peers displays:

>admin.removePeer("c74c94efb2c959c93d53c27de819998bdd2e5d07f901b91710de7a6857e4be466d97f9de7cfd5e9e08ce59f2fe6e152f9eb55726bb6ee0e9ab103da567c1543d")

Use admin.removeTrustedPeer for trusted peers, accordingly.
Note that the command is different from admin.add(Trusted)Peer in that it doesn’t contain an IP address and port, only the node ID.

You can also increase the verbosity of the node, so you get some more info for debugging purposes:

> debug.verbosity(4)

3 is the default, 5 will probably give you a headache. 4 is about right. You’ll see lots of messages scrolling by quickly now, giving you an in-depth look into what your node is doing, and maybe you even spot an issue worth reporting.

If you want to edit the arguments passed to efsn as it starts do this:

~# docker exec fusion /sbin/apk add nano
~# docker exec -it fusion /usr/bin/nano 
 docker-entrypoint-miner-local-gtw.sh

This installs the nano text editor inside the container first.

You can find all possible settings here or by calling efsn help.

Note that the Linux distribution running inside the container is Alpine, which is built to be lightweight. This has some implications, for example the sed you’ll find by default is a trimmed BusyBox version lacking some features like — follow-symlinks. You already know how to install the full (GNU) version of sed if you think you need it by looking at the example above.

You can also compile the node for yourself instead of using the prepared Docker container if you want to modify the source code (to change the hardcoded bootnodes for example). I’ll leave this here without further explanation, if you feel the need to compile something yourself you probably already know what to do with it anyway. Note that this is Ubuntu specific.

~# git clone https://github.com/FUSIONFoundation/efsn.git
~# add-apt-repository ppa:longsleep/golang-backports
~# apt-get update
~# apt-get install golang-go build-essential
~# cd efsn
~# make efsn

After the process completes, which might take a few minutes depending on the speed of your system, you can find and start the executable efsn binary as build/bin/efsn (you can also copy it somewhere else).
Since there’s no Docker container to do it for you, you have to assemble the start command yourself though. You can see it early when your container starts, it typically looks similar to this:

efsn 
 --datadir /var/lib/fusion/data 
 --unlock 0x0000000000000000000000000000000000000000 
 --password /var/lib/fusion/password.txt 
 --ethstats MyNode:[email protected] 
 --mine --autobt --port 40408 
 --rpc --rpcaddr=127.0.0.1 --rpccorsdomain=127.0.0.1 
 --rpcapi=eth,net,fsn,fsntx --rpcport 9000 
 --ws --wsaddr=127.0.0.1 --wsorigins=* 
 --wsapi=eth,net,fsn,fsntx --wsport 9001

Here’s an Ubuntu specific tl;dr version skipping all the explanations. Please read the whole article before asking on Telegram if this doesn’t work for you. I’m leaving out the ~# here and also added some options disabling interactive prompts, so you can more easily copy and paste the commands. The lines starting with # are comments, so they will be ignored if you accidentally paste them to the shell. They describe what you have to do manually in between. Some commands are wrapped for readability by putting an at the end of each line.

To add a peer (not a real node, don’t use it):

sudo docker exec -it fusion /usr/local/bin/efsn attach /fusion-node/data/efsn.ipc
admin.addPeer("enode://c74c94efb2c959c93d53c27de819998bdd2e5d07f901b91710de7a6857e4be466[email protected]203.56.113.178:40408")

To remove a peer:

sudo docker exec -it fusion /usr/local/bin/efsn attach /fusion-node/data/efsn.ipc
admin.removePeer("c74c94efb2c959c93d53c27de819998bdd2e5d07f901b91710de7a6857e4be466d97f9de7cfd5e9e08ce59f2fe6e152f9eb55726bb6ee0e9ab103da567c1543d")

If you need additional help, please join the official Telegram groups:
https://t.me/FUSIONFoundation for general Fusion discussions
https://t.me/FsnDevCommunity for development and node info

I’m also running a German-speaking group: https://t.me/FUSION_German

Become part of a friendly and helpful community, we’ll happily guide you!

Also follow these announcement channels for updates:
https://t.me/fusionannouncements
https://t.me/fusiondevelopersannouncement

My Telegram username is @Iruwen, you can find me in the above groups as well as in CoinMarketCap’s great international community where we discuss general crypto topics. I’ll gladly try to help you out with technical questions of all sorts.

If you think this was helpful in any way, feel free to buy me a beer!

FSN: 0x0afAB9b6dA9FBb79f3260F71E4a17d4AF9AC1020
ETH: 0x0afAB9b6dA9FBb79f3260F71E4a17d4AF9AC1020
BTC: 16yAtsdjzEaQbH8ucK1nbtkqrpo791EZ7a