Introduction
This document describes how to configure your Aeternity node installed using a release binary for joining a public network of nodes (e.g. testnet) knowing an initial network peer to join.
User-provided configuration
The aeternity
system supports user-provided parameters via a JSON- or YAML-formatted config file.
File name and location
The format of the config file is determined from the file extension: .json
for JSON, or .yaml
for YAML.
The location of the file can be specified in a few different ways, in order of priority:
- The OS environment variable
AETERNITY_CONFIG
contains a filename - The Erlang/OTP environment variable
-aecore config
contains a filename - A file named
aeternity.{yaml,json}
exists in${HOME}/.aeternity/aeternity/
- A file named
aeternity.{yaml,json}
exists in${AETERNITY_TOP}/
If all above checks fail, no user configuration is applied.
Validation
The contents of the config file will be validated against a JSON-Schema, located in the node at path data/aeternity_config_schema.json
. If any parameters violate the schema, the node will fail to start.
Environment variables
It is possible to set configuration values from the command line or shell scripts using
OS environment variables. The variable names correspond to a path in the config schema,
using the name prefix AE__
and with each level name, converted to uppercase, separated
by two underscores. Any hyphen ("-"
) is replaced by an underscore ("_"
).
Examples:
AE__PEERS
corresponds to {"peers": ...}
AE__HTTP__CORS__MAX_AGE
corresponds to {"http": {"cors": {"max_age": ...}}}
AE__HTTP__ENDPOINTS__DRY_RUN
corresponds to {"http": {"endpoints": {"dry-run": ...}}}
Simple configuration values (integers, strings, booleans) are given as-is. Structured values (arrays, objects) need to be encoded as JSON data.
Example: AE__MEMPOOL='{"tx_ttl":17,"sync_interval":4777}'
It is possible to provide an object definition and then override some specific value, as the variable names are processed in alphabetical order:
Example:
AE__MEMPOOL='{"tx_ttl":17,"sync_interval":4777}'
AE__MEMPOOL__SYNC_INTERVAL=9999
The OS environment variables are applied after reading any provided config file, so can be used to override a static user configuration.
Notable parameters
Peer-to-peer network
It is very important that a node not only can connect to other nodes, but that can accept incoming connections as well: the more peer connections (both inbound+outbound) the node has, the better its overall p2p network latency (i.e. block propagation time) will be.
By default node listen on TCP port 3015. It can be changed by sync
> port
parameter in the configuration file in case for some reason that port cannot be used (e.g. already used by other service).
Firewalls
Example setup: node (firewall) <-> firewall <-> Internet
If the node is behind a firewall that port (default 3015 or the one set in the configuration) should be opened for inbound TCP connections.
Note that the port may need to be opened both on the host machine running the node and any external device (firewall/router) that route the network traffic. Unfortunately all firewall configurations are different and common steps cannot be provided here, one should follow the documentation of their equipment/software "how to open firewall port".
NAT
Example setup: node <-> NAT (router) <-> Internet
If the node is behind NAT (e.g. home router) the port should be forwarded on that device to accept incoming connections from Internet and route it to the node.
Unfortunately all router configurations are different and common steps cannot be provided here, one should follow the documentation of their equipment/software "how to forward ports".
Advanced NAT
This is advanced configuration and should be used with caution because it can cause node misconfiguration and bad p2p connectivity.
In case the sync port (3015 by default) cannot be used as external forwarding port the sync
> external_port
configuration parameter can be used to change it. This is the port that the node will advertise to the network to be reached over Internet.
Example scheme: node (sync > port) <-> router (sync > external_port) <-> Internet
UPnP/NAT-PMP
If you don't have port forwarding configured in your router, but your router supports UPnP or NAT-PMP, the node provides UPnP/NAT-PMP service to streamline network configuration.
In order to start UPnP/NAT-PMP service:
- make sure UPnP/NAT-PMP is enabled on your router;
- in your user configuration file, set
sync
>upnp_enabled
parameter totrue
.
Then, the node will automatically create appropriate port mapping based on the configuration parameters.
Port Check
After you have started the node, you can verify the validity of your setup and configuration correctness by, for example, running the external node port check (assuming the default port 3015):
nc -zv $(curl -s https://api.ipify.org) 3015
Example output:
Connection to 203.0.113.27 3015 port [tcp/*] succeeded!
Where the IP address shown in the output is the external IP address of the node under test.
Channels
The node provides an infrastructure for using state channels. There are two distinct protocols involved:
- WebSocket client one
- Noise encoded one
The later is not subject to this document.
Channels' WebSocket client setup
In order to connect as a WebSocket client, one must set up a port and a host
the service is to listen at. This is a private node setting that is left for
the node operator to secure its access. The TCP port can be set using
websocket
> channel
> port
parameter. The address the service is to be
listening can be set using the websocket
> channel
> listen_address
parameter. Note that this address has a default value of 127.0.0.1
and thus
the WebSocket endpoint is not exposed.
Network ID
The network that the node connects to can be changed by setting fork_management
> network_id
in the configuration file.
The default network that the node package is preconfigured with is mainnet with ID ae_mainnet
.
The testnet (internally called UAT) has the network ID ae_uat
. To join the testnet set network_id
to ae_uat
in the configuration:
fork_management:
network_id: ae_uat
Hardforks
Hardforks allow the specification of consensus protocol versions with their respective heights for custom chains. Optionally, prefunded account and contract files can be speficied which will be effective at these heights. The files can be specified using the absolute path or a path relative to the home of the node in the directory data/aecore.
chain:
persist: true
hard_forks:
"genesis":
"height": 0
"accounts_file": hf_dir/genesis/accounts.json
"contracts_file": hf_dir/genesis/contracts.json
"first":
"height": 1800
"accounts_file": hf_dir/first/accounts.json
"second":
"height": 1100
It is also possible to set the configuration in an environment variable.
Example: AE__CHAIN__HARD_FORKS='{"1":{"acccounts_file": "hf_dir/genesis/accounts.json", "height":0}}'
Peers
Peers is a list of nodes that node tries to connect to.
If the peers
key is undefined (not set in the configuration file), the list of peers is automatically determined based on the Network ID configuration value. This works both for mainnet and testnet.
To prevent the node to initialize outgoing connections to any peers, set it to empty list:
peers: []
Please note that this do not prevent incoming connections, thus the node still might be connected to a network if its address is already known in that network.
Miner configuration
The instructions below assume that you already know your beneficiary
account public key (if you don't, see Beneficiary account section).
If you want to use your node to mine, you can use the default mining by setting
mining:
beneficiary: "beneficiary_pubkey_to_be_replaced"
autostart: true
in the aeternity.yaml configuration file.
Make sure you replace mining
> beneficiary
parameter with your public key!
Note that in order to improve sync performance, before configuring your miner, you should start a node with autostart: false
.
Change this value to autostart: true
when you are in sync, then restart the node.
Your mining setup needs to meet your hardware capacity. Therefore, you need to make a choice in how you want to configure your miner. You can read the documentation on setting up CUDA mining, or you can use all but one of the cores on your computer to mine (keep one core available for transaction gossiping, synchronising, etc). If you have 16 cores, you could (loosely spoken) assign 14 of them to mining using the following configuration:
mining:
beneficiary: "beneficiary_pubkey_to_be_replaced"
cuckoo:
edge_bits: 29
miners:
- executable: mean29-avx2
extra_args: -t 14
Combining different miners
Your mining setup may also contain multiple miners, which will be run simultaneously by your node. For example, to combine CPU miner with CUDA miner the following configuration can be used:
mining:
beneficiary: "beneficiary_pubkey_to_be_replaced"
cuckoo:
edge_bits: 29
miners:
- executable: mean29-generic
extra_args: -t 2
- executable_group: aecuckooprebuilt
executable: cuda29
extra_args: -t 1
hex_encoded_header: true
For more details on CUDA mining go to dedicated CUDA miner documentation.
Beneficiary account
In order to configure who receives fees from mining on a node, you must configure a beneficiary public key.
If you don't have your public key yet, you can generate a public/private key pair by using any one of the following tools:
If stratum is enabled, a beneficiary accounts from the stratum configuration are used instead, as stratum disables local mining.
For configuring stratum, please consult stratum operator user guide.
Generating a beneficiary account for testing purposes only
An alternative tool keys_gen
for generating a public-private key pair for testing purposes only is included in the package.
The key pair will be encrypted with a password that you shall pass to keys_gen
tool (below assumes the node is deployed in directory ~/aeternity/node
).
Generated public-private key pair will be located in ~/aeternity/node/generated_keys
, and public key is to be put in the configuration file (mining
> beneficiary
parameter).
Do make sure you back up ~/aeternity/node/generated_keys
(and remember the password): if you destroy the node, you can setup a new node and use the same account (public key) as a beneficiary.
You shall not share the private key (or the password) with anyone.
e.g.
cd ~/aeternity/node
bin/aeternity keys_gen my_secret_password ## This way of generating a key-pair is only for testing purpose, use a proper wallet/mechanism for your mainnet tokens: e.g., [AirGap wallet](https://airgap.it/).
Generated keypair with encoded pubkey: ak_2D9REvQsrAgnJgmdwPq585D8YksJC8PSAA8MscQdxinbkFC7rq
In the example the generated public key is ak_2D9REvQsrAgnJgmdwPq585D8YksJC8PSAA8MscQdxinbkFC7rq
, but do not use it in your config!
This is just an example value to show what public key format you should expect after running bin/aeternity keys_gen
command.
Example
The example below assume that:
- The node is deployed in directory
~/aeternity/node
; - You are aiming at joining mainnet.
If any of the assumptions does not hold, you need to amend the instructions accordingly.
Create the config file with the below content.
Place the config file in one of the locations specified in the File name and location section.
Make sure you amend the sync
> port
parameter with your actual value.
---
sync:
port: 3015
keys:
dir: keys
peer_password: "secret"
http:
external:
port: 3013
internal:
port: 3113
websocket:
channel:
port: 3014
mining:
autostart: false
chain:
persist: true
db_path: ./my_db
fork_management:
network_id: ae_mainnet
The node automatically creates the directory db_path
, for storing the blockchain, if not present.
The above sample config has mining
> autostart
set to false
, so mining will not start automatically.
To configure your node to mine, go to the Miner configuration section.
Note that YAML files have significant whitespace so make sure that you indent the file correctly and that the file ends with a newline.
You can validate the configuration file before starting the node:
cd ~/aeternity/node
bin/aeternity check_config aeternity.yaml
You shall read output like the following:
OK
If the file is valid YAML but does not contain a valid configuration, it prints a helpful output.
Database backend
Aeternity nodes support several types of database persistence backends:
- RocksDB (default for Unix, supported by Unix)
- Mnesia (default for Win32, supported by all OS'es)
You may choose the database backend by setting chain.db_backend
to the corresponding value rocksdb
, mnesia
RocksDB is only available under Unix compatible systems (including OS X and WSL) and is used there by default. RocksDB does not work with NTFS volumes.
Mnesia is the DB backend that is distributed with Erlang/OTP but is considered less performant than the other two. It is currently the default database when RocksDB is not available (i.e. Win32)
Notes:
- If using RocksDB,
db_path
should not point to an NTFS volume (like a mapped windows drive in WSL or volume mounts in Docker for Windows). - You can not switch the backend of an existing DB.
- Upgrading a node will automatically upgrade the DB structure. Downgrades would require an empty db and a full blockchain sync.
- Nodes can not simultaneously work with the same DB files. However it is possible to make snapshots which could be used to speed up syncing of new nodes.
- Initial sync might take a lot of time and that heavily depends on the available CPU/IOPS.
- Restarting a node might be slow on certain configurations due to intensive DB consistency checks.
RocksDB-related settings
Two configuration settings modify how the RocksDB backend operates, shown below with their default values:
chain:
db_commit_bypass: true
db_direct_access: false
The chain:db_commit_bypass
option allows for turning off a special optimization used to speed up and make atomic updates to rocksdb tables from a mnesia transaction commit. This optimization is active by default, and should only be turned off if it's suspected to cause problems.
The chain:db_direct_access
option makes the Aeternity node use a different API, mrdb
, for all database accesses. This API is faster and should have better safety properties, but since it is new, it isn't yet the default when using the RocksdbDB backend.
The db_migrate
script
When initializing a new node using the RocksDB backend in current or future releases, mnesia tables are created as 'column families' - a form of logical tables supported by recent versions of RocksDB. This should improve both speed and consistency, as well as drastically lower the number of open file descriptors.
If using an existing database, the old model with one database instance per table will be kept, until the bin/aeternity db_migrate
script is executed. This script, which will activate maintenance mode during its operation, will convert all tables to column families. It will take a while, but should complete within ca 2 hours.
Troubleshooting
If an error occurs during migration, you will need to address the error and try to complete the migration, as the system is unlikely to work correctly after a partial migration.
The script should leave the node in 'maintenance mode' after a failed migration. If the node died, try starting the node using e.g. AE__SYSTEM__MAINTENANCE_MODE=true bin/aeternity console
and re-run the db_migrate
script. If this doesn't work, fall back to synching the node from scratch, or download a good database snapshot and restart from there.