diff --git a/README.md b/README.md index 8fefd3f..49e6202 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,213 @@ # Gajumaru Hive Client -When running tests locally: +This application is primarily meant to be used by the [GajuMine](https://git.qpq.swiss/QPQ-AG/gajumine) +application, but can also be run as a headless worker. It can be built either using `rebar3` or +using [`zx`](https://zxq9.com/projects/zomp/) (recomended). -`rebar3 shell` +## Operation +The `gmhive_client` needs at least a worker public key to operate. +It first queries the [GajuMining website](https://gajumining.com) to find the address of +the Gajumaru Hive server, which it then connects to. GajuMining won't provide the address +unless the public key is a registered worker. -If connecting to the `testnet` hive: -`GMMP_CLIENT_CONFIG=gmhc_config-testnet.eterm rebar3 shell` +## Configuration -If connecting to a `testnet` hive running locally: -`GMHC_CONFIG=gmhc_config-testnet-local.eterm rebar3 shell` +The Hive Client uses a configuration schema ([see below](#json-schema)). +At a minimum, a value for `"pubkey"` must be provided. All other configuration +items have usable defaults. + +Examples: + +**.json**: +```json +{ "pubkey" : "ak_2NQoybA6uyvhu3cdzWFtZnxCZpZvKE5TxjYB3hB7kMWEquwLVY", + "extra_pubkeys" : [ "ak_2Dfwyb7ZFhcAELoxgWyMCkVnpZUhwUm6aftKcv6dakagePWyx9" ] +} +``` + +**.eterm**: +```erlang +#{ <<"pubkey">> => <<"ak_2NQoybA6uyvhu3cdzWFtZnxCZpZvKE5TxjYB3hB7kMWEquwLVY">>, + <<"extra_pubkeys">> : [ <<"ak_2Dfwyb7ZFhcAELoxgWyMCkVnpZUhwUm6aftKcv6dakagePWyx9">> ] + }. +``` + +Configuration can be provided in a file, where the filename extension defines +the format: `".json"` for JSON format, `".eterm"` for Erlang term format. +In the case of Erlang term format, the data should be on "internal JSON form", +i.e. nested maps, where all strings are of type `binary()`. + +By default, the Hive client looks for a configuration file named +`"gmhive_client_config.[json|eterm]"` in the current working directory. +A specific configuration file can be identified using the OS environment +variable `GMHIVE_CLIENT_CONFIG`. + +On invocation, individual configuration items can be set in one of two ways: + +### OS environment variable overrides + +By creating an OS environment variable with the name `GMHC__`, +an individual variable can be redefined. The name is composed from the +configuration key name, converted to uppercase, and with `__` as a delimiter +for a nested key. The value is coerced into the expected type using the schema. +Complex values are given in JSON format - be sure to quote it. + +Example: +``` +GMHC__PUBKEY="ak_2Dfwyb7ZFhcAELoxgWyMCkVnpZUhwUm6aftKcv6dakagePWyx9" zx run uwiger-gmhive_client +``` + +``` +GMHC__WORKERS='[{"executable": "mean29-avx2"}]' zx run ... +``` + +### Command-line arguments + +Arguments on the form `-gmhc Key Value` can be added to the command line. +The key name is derived from the schema, all lowercase and with `__` as delimiter. + +Example: +``` +zx run uwiger-gmhive_client -gmhc pubkey ak_2Dfwyb... +``` + +### Considerations + +The values for `pool_admin` and `pool` should be left alone. The `"network"` +configuration item is special. Its default value is `"mainnet"`, which +indicates that the client should connect to +[gajumining.com](https://gajumining.com) to find the hive server, but by +changing its value to `"testnet"`, (or to other networks in the future,) not +only does this inform the client of the network for which the client should +mine, but it also changes what URL the client will use to find the hive +server. (For `"testnet"` this will be `"test.gajumining.com"`.) + +## JSON Schema + +```json +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "additionalProperties": false, + "properties": { + "extra_pubkeys": { + "default": [], + "description": "Additional worker pubkeys, sharing rewards", + "items": { + "pattern": "^ak_[1-9A-HJ-NP-Za-km-z]*$", + "type": "string" + }, + "type": "array" + }, + "network": { + "default": "mainnet", + "type": "string" + }, + "pool": { + "additionalProperties": false, + "properties": { + "host": { + "default": "127.0.0.1", + "description": "Hostname of hive server", + "example": "0.0.0.0", + "type": "string" + }, + "id": { + "description": "Pool contract id", + "pattern": "^ct_[1-9A-HJ-NP-Za-km-z]*$", + "type": "string" + }, + "port": { + "default": 17888, + "description": "Hive server listen port", + "minimum": 1, + "type": "integer" + } + }, + "type": "object" + }, + "pool_admin": { + "additionalProperties": false, + "properties": { + "default_per_network": { + "additionalProperties": false, + "properties": { + "mainnet": { + "default": "https://gajumining.com/api/workers/{CLIENT_ID}", + "type": "string" + }, + "testnet": { + "default": "https://test.gajumining.com/api/workers/{CLIENT_ID}", + "type": "string" + } + }, + "type": "object" + }, + "url": { + "default": "https://test.gajumining.com/api/workers/{CLIENT_ID}", + "description": "URL of Eureka worker api", + "type": "string" + } + }, + "type": "object" + }, + "pubkey": { + "description": "Primary client pubkey", + "pattern": "^ak_[1-9A-HJ-NP-Za-km-z]*$", + "type": "string" + }, + "type": { + "default": "worker", + "description": "monitor mode can be used to see if a pool is alive", + "enum": [ + "worker", + "monitor" + ], + "type": "string" + }, + "workers": { + "default": [ + { "executable": "mean29-generic" } + ], + "description": "Definitions of workers' configurations. If no worker are configured one worker is used as default, i.e. 'mean29-generic' executable without any extra args.", + "items": { + "additionalProperties": false, + "properties": { + "executable": { + "default": "mean29-generic", + "description": "Executable binary of the worker. Can be a fully qualified path, but the software may apply default logic to locate a plain basename.", + "type": "string" + }, + "extra_args": { + "default": "", + "description": "Extra arguments to pass to the worker executable binary. The safest choice is specifying no arguments i.e. empty string.", + "type": "string" + }, + "hex_encoded_header": { + "default": false, + "description": "Hexadecimal encode the header argument that is send to the worker executable. CUDA executables expect hex encoded header.", + "type": "boolean" + }, + "instances": { + "description": "Instances used by the worker in case of Multi-GPU mining. Numbers on the configuration list represent GPU devices that are to be addressed by the worker.", + "example": [0,1,2,3], + "items": { "type": "integer" }, + "minItems": 1, + "type": "array" + }, + "repeats": { + "default": 1, + "description": "Number of tries to do in each worker context - WARNING: it should be set so the worker process runs for 3-5s or else the node risk missing out on new micro blocks.", + "type": "integer" + } + }, + "required": [ + "executable" + ], + "type": "object" + }, + "type": "array" + } + }, + "type": "object" +} +```