A Monero mining pool server written in C.
Design decisions are focused on performance and efficiency, hence the use of libevent and LMDB. Currently it uses only two threads under normal operation (one for the stratum clients and one for the web UI clients). It gets away with this thanks to the efficiency of both LMDB and libevent (for the stratum clients) and some sensible proxying/caching being placed in front of the web UI.
Configuration is extremely flexible, now allowing for the pool to run in a variety of setups, such as highly available and redundant configurations. Discussed further below in: Interconnected pools.
This pool was the first pool to support RandomX and is currently the only pool which supports the RandomX fast/full-memory mode.
The single payout mechanism is PPLNS, which favors loyal pool miners, and there are no plans to add any other payout mechanisms or other coins. Work should stay focussed on performance, efficiency and stability.
The pool also supports an optional method of mining whereby miners select their own block template to mine on. Further information can be found in the document: Stratum mode self-select.
For testing, a reference mainnet pool can be found at monerop.com.
The build system requires the Monero source tree to be cloned and compiled. Follow the instructions for compiling Monero, then export the following variable:
export MONERO_ROOT=/path/to/cloned/monero
Replacing the path appropriately.
Beyond the Monero dependencies, the following extra libraries are also required to build the pool:
As an example, on Ubuntu, these dependencies can be installed with the following command:
sudo apt-get install liblmdb-dev libevent-dev libjson-c-dev uuid-dev
After installing all the dependencies as described above, to compile the pool as a release build, run:
make release
The application will be built in build/release/
.
Optionally you can compile a debug build by simply running:
make
Debug builds are output in build/debug/
.
During compilation, a copy of pool.conf is placed in the output build directory. Edit this file as you see fit. When running the pool, if a custom location is not set via the command-line parameter `--config-file
monerod ... --block-notify '/usr/bin/pkill -USR1 monero-pool'Launching `monerod` like this instructs it to send the required signal, *SIGUSR1*, to the pool whenever a new block is added to the chain. Using this mechanism has a *significant* benefit - your pool *immediately* knows when to fetch a new block template to send to your miners. You're essentially giving your miners a head-start over miners in pools which use polling (which is what currently all the other pool implementations do). ### Interconnected pools In some situations it's desirable to run multiple pool instances that behave as one. Some examples being: - When running a global public pool, it's desirable to offer extremely low-latency pool connections to geographically dispersed miners. - When running a private pool across multiple data centers, it's desirable to make use of the internal site-to-site network makeup. - Where there are multiple hosts available, it's desirable to offer extra redundancy. To meet these needs, multiple instances of the pool can be run with each behaving either as an edge pool, an upstream pool, both (i.e. bridged) or a normal single pool. Any pool that has an upstream pool configured does almost everything a normal pool does, with the exception that it offloads payout processing to its upstream pool, thus it relays validated shares and blocks to the upstream pool. In return, the upstream pool sends the combined pools stats, balance updates and handles the payout processing. Should an upstream become unreachable, the downstream pools continue as normal, then upon reconnection to the upstream, sends over the backlog of shares and blocks accumulated whilst the upstream was unreachable. Configuration is fairly trivial. A pool that will allow downstream pools to connect to it, does so via the config file parameters `trusted-listen`, `trusted-port` and `trusted-allowed`. E.g. trusted-listen = 10.0.0.1 trusted-port = 4244 trusted-allowed = 10.0.0.2,10.0.0.3 As share validation is performed on the edge pools, it's ***vitally*** important this trusted listener is secured. Ideally it's only bound to an internal / local network / private interface and specifying the IP addresses of the downstream pools allowed to connect to it (as in the example above). If the interface being bound to is already secured, the parameter `trusted-allowed` can be omitted. Then the downstream pools (`10.0.0.2` and `10.0.0.3` in the above example), need to include in their config files the parameters `upstream-host` and `upstream-port`. E.g. upstream-host = 10.0.0.1 upstream-port = 4244 To create a bridged pool, use all five parameters discussed above. For example: trusted-listen = 10.0.0.4 trusted-port = 4244 trusted-allowed = 10.0.0.5,10.0.0.6 upstream-host = 10.0.0.1 upstream-port = 4244 An example where bridging can be useful is for spanning network providers, e.g. using a global provider for the main pool hubs (the bridges) and local providers for edge pools within a territory. Every pool, however configured, still needs RPC access to a Monero daemon. They can of course all be configured to use the *same* daemon, or for extra redundancy, make use of separate daemons. Downstream pools do not need RPC access to the pool's wallet, only the final upstream needs wallet access. If Stratum mode self-select is being offered, the pool wallet view key can be set in the downstream pool config files via the `pool-view-key` parameter, or by running a local view-only wallet RPC. ## Running Ensure you have your Monero daemon (`monerod`) and wallet RPC (`monero-wallet-rpc`) up and running with the correct host and port settings as defined in your pool config file. It is highly recommended to run these on the same host as the pool server to avoid any network latency when their RPC methods are called. Then simply `cd build/[debug|release]` and run `./monero-pool`. ### Command-line parameters A few of the configuration options can be overridden via the following command-line parameters: -c, --config-file