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
datadirneeds to exist and be owned by the user that is running theelvmasterdserver/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 thedatadirneeds 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 -
elvmasterdwill look in thedatadirfor akeystoredirectory. 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
mnemonicneeds 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
passphrasesecures 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.