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://c74c94efb2c959c93d53c27de819998bdd2e5d07f901b91710de7a6857e4be466d97f9de7cfd5e9e08ce59f2fe6e152f9eb55726bb6ee0e9ab103da567c1543d@[::]:40408

INFO [01-03|15:34:22.551] RLPx listener up self=enode://c74c94efb2c959c93d53c27de819998bdd2e5d07f901b91710de7a6857e4be466d97f9de7cfd5e9e08ce59f2fe6e152f9eb55726bb6ee0e9ab103da567c1543d@[::]: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://c74c94efb2c959c93d53c27de819998bdd2e5d07f901b91710de7a6857e4be466d97f9de7cfd5e9e08ce59f2fe6e152f9eb55726bb6ee0e9ab103da567c1543d@[::]: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://c74c94efb2c959c93d53c27de819998bdd2e5d07f901b91710de7a6857e4be466d97f9de7cfd5e9e08ce59f2fe6e152f9eb55726bb6ee0e9ab103da567c1543d@[::]: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:

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://c74c94efb2c959c93d53c27de819998bdd2e5d07f901b91710de7a6857e4be466d97f9de7cfd5e9e08ce59f2fe6e152f9eb55726bb6ee0e9ab103da567c1543d@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://id@ip:port",

"enode://id@ip:port",

"enode://id@ip: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/, /,

/g'|sed 's/\[/[

/;s/\]/

]/'

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: