Configurations
elvmasterd
elvmasterd
configuration .toml
[node]
section
This is the main part of the config. Most parameters are set here.
-
Change this value to a name that identifies the Fabric Node to humans:
identity = "some-name-that-is-descriptive"
-
The
datadir
needs to exist and be owned by the user that is running theelvmasterd
server/daemon. The log location should also be readable/writable by the same user. Based on log retention policies and storage layout, these should be different volumes and thedatadir
needs to be the fast, large storage noted in the specifications.datadir = "/var/elvmasterd/data" log_file = "/var/elvmasterd/log/elvmasterd.log"
-
These parameters should not change, but using different ports is possible given security restraints on the deployment.
port = 40304 rpcaddr = "127.0.0.1" rpcport = 8545
-
elvmasterd
will look in thedatadir
for akeystore
directory. By default it will use the first available keys in this dir. To pin the right address, please use the explicit hex address for the wallet/key. Note, this is the address noted in the partition section.node_account = "0x1234abcd..."
This account will be setup later on. Just note that it will need to be set.
NOTE: A value not mentioned, but does need consideration is ipcpath
, which is set to /tmp/elvmasterd.socket
. This socket can be used by anyone with read access to it to connect in with the unlocked wallet. Adequate measures should be used to secure this socket.
[hdwallet]
section
The following wallet parameters are used to either generate (via elvmasterd wallet create
) or in securing/accessing the wallet on setup/startup.
-
The
mnemonic
needs to be a 12 word phrase that confirms to BIP 39. This is used to generate a seed for the wallet. This can be set at the CLI, or left unset and the wallet creation (only time this is used) will generate one on the fly. If using the generated mnemonic, it is printed in the logs. This mnemonic should be saved and kept secret like a password/passphrase as it can be used to recover or regenerate a wallet.:mnemonic = ""
-
The
passphrase
secures the wallet on disk. Pick a strong one.passphrase = ""
Key Generation
All Fabric Nodes need to have a unique wallet. The address of the wallet is used to identify the Fabric Node and is used in the enode
that is used by chain participants to locate a system.
In the config above, the [hdwallet]
section is used to create this, but the parameters can also be from the CLI. For the purpose of documenting key generation, both the config set parameters, and the CLI passed version will be shown.
These examples presume the datadir
exists and the config file is placed in /etc/elvmasterd
as config.toml
(and is readable).
Keygen - Config only
/usr/local/bin/elvmasterd wallet create --config /etc/elvmasterd/config.toml
Keygen - CLI only
With supplied mnemonic:
/usr/local/bin/elvmasterd wallet create --datadir /var/elvmasterd-data --passphrase "uber-secret" --mnemonic "word1 ... word12" -n 1
Without supplied mnemonic:
/usr/local/bin/elvmasterd wallet create --datadir /var/elvmasterd-data --passphrase "uber-secret" -n 1
Keygen output
# /usr/local/bin/elvmasterd wallet create --datadir /var/elvmasterd-data --passphrase "uber-secret" -n 1
INFO [12-21|01:12:08.207] keystore dir=/var/elvmasterd-data/keystore
WARN [12-21|01:12:08.213] no user mnemonic specified. creating random value mnemonic="word1 ... word12"
INFO [12-21|01:12:08.241] derive path wallet_path=m/44H/60H/0H/0/0
INFO [12-21|01:12:08.244] node account address=0xa4f2d5Ff017336Fa416949d1C2DD7c52A772df94
WARN [12-21|01:12:08.244] encrypting keystore account with default password password=uber-secret
INFO [12-21|01:12:10.343] Available accounts
INFO [12-21|01:12:10.343] account[0] TargetAddr=0xa4f2d5ff017336fa416949d1c2dd7c52a772df94
NOTE: In this sample output, the 0xa4f2d5Ff017336Fa416949d1C2DD7c52A772df94
address should be used in the configuration for node_account
noted above.
Full Sample elvmasterd.toml
The following example elvmasterd
configuration can enable validation, provided the directories and files specified are created/exist.
enc_block = "H4sIAAAAAAAA/6yUz47jNgzG30VnH6g/lMQcix5aoNc+AEmRE6NJnCYOMNtF3r3IzjYLbC8ezOhG2v6Zn/R9+hp0Ofn8EnZfg+55Pv0+wo4QM+AU9svRrqvx+OWw6F9hB1Ow+RwRfq5/4+s+7AK8wgdX+E7En/7Qf9Ty5R8+rfPt+KOlh/nvmz0knO0yL+Ptu/Oi+7CLAHC/T+G0nNTeZgxTWOeHMj6enx17XS/8K6/8KTq0e6qSKrbBXXNqvbbMpUYwcxBwJYXRR84GRLVJslRUBWrHApGxgI6YE7Jnq8kaupeIppF0qPXC3Myl8sCUurgn7d1UyMS1kMcOEBOJZ7TSwHrJQgwSQbRiQVUamVhrx9xSKrGRtRydqBWNkdzQvGX96D58fIUpvPD1j/k4r99OJuaYxrf2mN1nvR3WL28PwhSO8+tnWlGX+SR8tXfxwhT4cFj0Ycetx/t4V/jA/1mUsTqjEEEkRu3fyfcpoKbcZQzVaLmUrFg0EmXCXDCjJ8NcHev/iKN1E0XWmp6w2iI6iUht5obUwUdPMmQQNM6xZnTOrW2CbbXodq3EDK5dPGbj3gzAYqlavWXpDQSkegTWTeNtTcb28bZm/B3EjancTjSJHaGhYMucuYCmVhChsvRILhUrGTNt2kLzREJRMqTUAY37IGQX8UIwAFKJRC3BBtjjQr4dxS7P+/eFr39ebTzrM1/stH5emu//BgAA//9rsh4v6gYAAA=="
[node]
identity = "some-validator"
datadir = "/var/elvmasterd/data"
networkid = 955305
port = 40304
nodiscover = false
ipcenable = true
ipcpath = "/tmp/elvmasterd.socket"
rpcaddr = "127.0.0.1"
rpcport = 8545
rpccorsdomain = "*"
node_account = ""
verbosity = 4
log_file = "/var/elvmasterd/log/elvmasterd.log"
log_rotate = true
log_maxbackups = 5
log_maxage = 6
log_maxsize = 100
discovery_urls = "enrtree://ANSPCRAV5TS5FGBBXB7ERZBRUCTS4BLXOF7BQIELODCLLZE2BR2U4@main955305.nodes.cfab.app"
[hdwallet]
mnemonic = ""
passphrase = ""
accounts = 1
elvmasterd
systemd
Unit
elvmasterd
should be run with some form of process management, like systemd
to ensure the daemon loads on system boot, and reloads when failures occur.
[Unit]
Description=Eluvio elvmasterd
After=network.target
[Service]
User=eluvio
Group=eluvio
Type=simple
Restart=always
RestartSec=30s
ExecStart=/usr/local/bin/elvmasterd start \
--config=/etc/elvmasterd/config.toml \
--log-file=/var/elvmasterd/log/elvmasterd.log
[Install]
WantedBy=default.target
The attached versions highlight other scenarios that will work, but may not be documented in detail otherwise.
qfab
Below are the main sections that need per-host configuration.
.paths
section
From there the main paths used to determine where parts are stored is defined:
{
"paths": {
"install_path": "/var/qfab/QDATA",
"qparts_path": "/var/qfab/QDATA/PARTS",
"qtemp_path": "/var/qfab/QDATA/TMP",
"qlibs_path": "/var/qfab/QDATA/LIBS",
"node_path": "/var/qfab/QDATA/LOCAL",
"cache_path": "/var/qfab/CACHE"
},
The sample uses the /var/qfab
storage location noted in the setup documentation.
.fabric.node_id
parameter
Each nodes is identified by an ID, and this ID is placed in the configuration file. The Node ID is an encoding of the node_account
that is created when the wallet is generated. Using the example address from the elvmasterd
configuration above (0xa4f2d5Ff017336Fa416949d1C2DD7c52A772df94
), use the qfab tools format-id
CLI to format in the right encoding:
$ qfab tools format-id -t node 0xa4f2d5Ff017336Fa416949d1C2DD7c52A772df94
inod3JHWWWSUKxMFuAi27fUXroyBhxE7
This value then replaces the REPLACE_ME
in the example config, like so
{
"fabric": {
"node_id": "inod3JHWWWSUKxMFuAi27fUXroyBhxE7",
.api.listeners[]
array
Each array item is a simple object like so:
{
"base_url": "/tmp/qfab.socket"
}
The .base_url
can be a socket or an HTTP
/HTTPS
URI. If an HTTPS
URI, then the object can also include CA and key data passed along.
In the example in the config, a socket and localhost listener on port 8008
is created.
{
"api": {
"listeners": [
{
"base_url": "/tmp/qfab.socket"
},
{
"base_url": "http://127.0.0.1:8008"
}
],
.log.level
parameter
It may be useful to change this to info
or debug
if troubleshooting errors
{
"log": {
"level": "debug",
.qspaces[]
array
Each array item defines a space the node participates in. In the exmaple config a single space is defined:
{
"id": "ispc2RUoRe9eR2v33HARQUVSp1rYXzw1",
"type": "Ethereum",
"names": [
"main"
],
"ethereum": {
"url": "/tmp/elvmasterd.socket",
"wallet_file": "/var/elvmasterd/keystore/UTC...",
"network_id": 955305,
"dao": {
"enabled": true,
"interval": "1s"
}
}
}
The .ethereum.url
can be a socket or an HTTP
/HTTPS
URI that the elvmasterd
presents to get access to the Web3 APIs. It is advised to keep this as a socket.
The .ethereum.wallet_file
is the wallet/key file generated above
qfab
configuration .json
Full Sample qfab.json
The following example qfab
configuration can enable validation, provided the directories and files specified are created/exist.
{
"paths": {
"install_path": "/var/qfab/QDATA",
"qparts_path": "/var/qfab/QDATA/PARTS",
"qtemp_path": "/var/qfab/QDATA/TMP",
"qlibs_path": "/var/qfab/QDATA/LIBS",
"node_path": "/var/qfab/QDATA/LOCAL",
"cache_path": "/var/qfab/CACHE"
},
"fabric": {
"skip_part_checks": true,
"node_id": "REPLACE_ME",
"network": {
"id": "ispc2RUoRe9eR2v33HARQUVSp1rYXzw1",
"names": [ "main" ],
"seed_nodes": [ "38.142.50.106", "60.240.133.202" ]
},
"net": {
"routing_protocol": {
"partition_strategy": {
"partition_level": 4,
"partition_num": 1,
"partition_replication": 2,
"archive_nodes": [
"inodBzkjwDzHMy8gYPJEr5tHDtPSubP",
"inodX38Ag8Zv3dgZ8GBpt4uDLU17DR4",
"inod3SNhxjib1zwsbaPd6qQrssYMzjGV",
"inod4rCfYkpMHeqRz6F1h3gXPeXLCBq",
"inodBkzb4tHyvFLJqDbuhzRYHtbZnD4",
"inod3xqm6WzXPF9KrLoCeB6AJG7TPhGN",
"inod2Guf82eKGYfPH5jEW7giVFkQKxxF",
"inod39yyg65Jw1YsrNR9SegoJdGBc6EG",
"inod4CyWjqrnPAxkxeWLpCzzafPqGB4U",
"inod47KtntQ5uvpPS4oWB4GhTtZhYgC1"
]
}
},
"http": {
"max_conns_per_host": 2000,
"max_idle_conns": 5000,
"max_idle_conns_per_host": 1000,
"idle_conn_timeout": "3m"
},
"transport_protocol": {
"type": "http",
"http": {
"timeout": "120s"
}
}
}
},
"gc": {
"enabled": true,
"interval": "1h"
},
"usage": {
"enabled": true,
"part_duration": "12h",
"object_duration": "24h",
"worker_num": 32,
"process_interval": "30m",
"process_wait_interval": "15m"
},
"api": {
"listeners": [
{
"base_url": "/tmp/qfab.socket"
},
{
"base_url": "http://127.0.0.1:8008"
}
],
"cors": {
"allowed_origins": [
"*"
],
"allowed_methods": [
"GET",
"POST",
"PUT",
"DELETE",
"OPTIONS"
],
"allowed_headers": [
"*"
],
"max_age": 600,
"debug": false
},
"log_body_max": "64KB"
},
"log": {
"level": "warn",
"formatter": "text",
"file": {
"filename": "/var/qfab/logs/qfab.log",
"maxsize": 1000,
"maxage": 0,
"maxbackups": 10
},
"named": {
"/eluvio/qfab/daemon": {
"level": "info"
}
}
},
"llvm": {
"execution_engine_cache": {
"enabled": true,
"size": 20
},
"port_range": "7000:7100"
},
"avpipe": {
"persistent": "leveldb",
"drm_required": false,
"cache": {
"path": "leveldb",
"audio_page_segments": 20000,
"video_page_segments": 20000,
"manifests": 2000,
"metas": 2000,
"abr_infos": 2000,
"captions": 2000
}
},
"decryption": {
"pool": {
"max_workers": 8,
"input_queue_size": 99
},
"buffer_size": "128MB"
},
"metrics": {
"type": "expvar",
"collectors": {
"avpipe": {
"period": "120s",
"enabled": true
}
}
},
"qspaces": [
{
"id": "ispc2RUoRe9eR2v33HARQUVSp1rYXzw1",
"type": "Ethereum",
"names": [
"main"
],
"ethereum": {
"url": "/tmp/elvmasterd.socket",
"wallet_file": "/var/elvmasterd/keystore/UTC...",
"network_id": 955305,
"dao": {
"enabled": true,
"interval": "1s"
}
}
}
]
}
qfab
systemd
Unit
qfab
should be run with some form of process management, like systemd
to ensure the daemon loads on system boot, and reloads when failures occur.
[Unit]
Description=Eluvio elvmasterd
After=network.target
[Service]
User=eluvio
Group=eluvio
Type=simple
LimitCORE=500000
LimitNOFILE=500000
Restart=always
RestartSec=2s
Environment=CUDA_DEVICE_ORDER=PCI_BUS_ID
ExecReload=/bin/kill -HUP $MAINPID
ExecStart=/usr/local/bin/qfab daemon --config /etc/qfab/qfab.json
[Install]
WantedBy=default.target
The attached versions highlight other scenarios that will work, but may not be documented in detail otherwise.