mkpool is a high-performance, multi-threaded mining pool written in modern C++23. It speaks Stratum V1, Stratum V1-over-TLS, and native Stratum V2 (Noise-encrypted), and runs nine coin families (including merge-mined Dogecoin and Equihash Zcash) out of a single codebase.
Scope: This repository is the pool engine, published for transparency. The operational stack that surrounds it in production (the database/analytics service, the public REST API, and the website) is not part of this open release.
mkpool is an original codebase. The async C++ engine, multi-coin support, Stratum V2 (Noise) and TLS stack, per-miner solo coinbase construction, and security tooling were all written from scratch. The one component that intentionally borrows from ckpool (Con Kolivas' GPLv3 C pool) is the variable-difficulty retarget math, a small, attributed re-implementation of a well-proven algorithm. mkpool is GPLv3-licensed, the same as ckpool (see Attribution & License).
Status: Live on mainnet. Stratum V2 (Noise), TLS stratum, and all nine chains are in production. This README reflects the deployed state.
Legend: ✅ supported ·
| Capability | mkpool | ckpool |
|---|---|---|
Stratum V1 (mining.*) |
✅ | ✅ |
Stratum V1 over TLS (stratum+ssl://) |
✅ in-binary any_stream variant, SIGHUP cert reload |
❌ |
Stratum V2 native (Noise NX handshake, encrypted) |
✅ full-block mode, collects fees | ❌ |
| SV2 secret-authority key / signed certs | ✅ | ❌ |
SV2 empty-block vs full-block toggle (v2EmptyBlocks) |
✅ | ❌ |
BIP310 mining.configure (version-rolling negotiation) |
✅ | ✅ |
ASICBoost / version-mask (version_mask) |
✅ validated (BIP310) | ✅ |
subscribe-extranonce extension |
✅ | ✅ |
Suggested difficulty (mining.suggest_difficulty, d= in password) |
✅ clamped per coin | ✅ |
| Capability | mkpool | ckpool |
|---|---|---|
| Bitcoin (BTC, SHA-256d) | ✅ | ✅ |
| Bitcoin Cash (BCH, SHA-256d, CashAddr) | ✅ | ❌ |
| Bitcoin SV (BSV, SHA-256d) | ✅ | ❌ |
| Fractal Bitcoin (FB, SHA-256d) | ✅ | ❌ |
| eCash (XEC, SHA-256d + Avalanche pre-consensus) | ✅ | ❌ |
| DigiByte (DGB, SHA-256d) | ✅ | ❌ |
| Litecoin (LTC, Scrypt) | ✅ | ❌ |
| Dogecoin merge-mined on LTC (AuxPoW) | ✅ parent + aux blocks | ❌ |
Zcash (ZEC, Equihash 200,9, mining.set_target) |
✅ | ❌ |
| Single codebase, per-coin config | ✅ 9 families | ❌ Bitcoin-only |
| Equihash share validation (in-process) | ✅ equihash.hpp + unit test |
❌ |
| Blossom-aware subsidy / halving (ZEC) | ✅ | ❌ |
| Capability | mkpool | ckpool |
|---|---|---|
| Language / standard | C++23 | C |
| Concurrency model | Single-process, async io_context worker pool (std::jthread) |
Multi-process (fork) + threads, Unix-socket IPC |
| Networking | Boost.Asio / Beast, per-session strand | Hand-coded epoll + Unix sockets |
| Session map | Sharded (default 64 shards), low-contention broadcast | Hash tables (uthash) |
| Per-session write path | WriteQueue + 1 MiB watermark (no async_write races) |
epoll-driven send buffers |
| Job/work window | JobWindow rolling buffer (default 32 jobs) keyed by job_id |
Workbase list |
| New work on block change | ✅ full tx set, ZMQ-driven, no transactionless work | ✅ |
| ZMQ block-hash notification | ✅ edge-trigger bug fixed | ✅ (optional) |
bitcoind failover (multiple nodes) |
✅ | ✅ |
| Solo coinbase (miner address = username) | ✅ per-session coinbase2 rebuild | ✅ (BTCSOLO mode) |
| Operator fee / donation from coinbase | ✅ configurable %, incl. aux/DOGE split | ✅ default 0.5% |
| Custom coinbase signature | ✅ /mkpool.com/ mandated |
✅ configurable |
| Proxy mode | ❌ | ✅ |
| Passthrough / node / redirector modes | ❌ | ✅ |
| Seamless restart via socket handover | ❌ (systemd restart per coin) | ✅ |
| Capability | mkpool | ckpool |
|---|---|---|
| Vardiff (EMA / decaying-average) | ✅ faithful re-impl of ckpool decay_time/time_bias |
✅ (original) |
| Per-coin vardiff ranges | ✅ (e.g. BTC/BCH/BSV/DGB/XEC/FB [1024, 1M], ZEC [8192, 524288]) |
mindiff/maxdiff |
| Fixed-difficulty tiers (one TCP port each) | ✅ e.g. 10M / 50M / 100M ports | |
Custom d= clamp (1024-10M) |
✅ | |
| ntime validation (BIP113-compatible) | ✅ utils::valid_ntime |
✅ |
int64_t coinbase value (overflow-safe) |
✅ end-to-end | ✅ |
| Local address validation (no RPC per authorize) | ✅ BIP173/BIP350/base58/CashAddr decoders |
| Capability | mkpool | ckpool |
|---|---|---|
| Token-bucket per-IP rate limiting | ✅ | |
| Auto-ban on excessive invalid shares | ✅ | |
fail2ban + nftables integration (per-IP conn cap) |
✅ documented | ❌ |
| Connection-drop observability (per-disconnect logs) | ✅ reason/worker/lifetime/shares | |
| Sanitizer builds (ASan / TSan / UBSan) | ✅ CMake options + scripts/run_sanitizers.sh |
❌ |
| Unit tests (Catch2 / Catch-style) | ✅ merkle, vardiff, address, SV2 noise, etc. | ❌ |
| Stratum fuzzing harness | ✅ scripts/fuzz_*.sh (7 abuse categories, daemon-survival assertions) |
❌ |
| Build system | CMake + Ninja | autotools (./configure && make) |
| Platform | Linux (Ubuntu 24.04+) | Linux |
| External dependencies | Boost, OpenSSL, libpq/pqxx, libzmq, libsodium | Minimal (glibc, yasm, optional zmq) |
Where ckpool still wins: ckpool's proxy / passthrough / redirector / node topology lets it fan a single upstream pool out to millions of clients with near-zero per-client overhead, and its socket-handover restart is genuinely seamless. mkpool is a single-process solo-pool engine and does not implement those scale-out roles (yet). It trades that for encryption, multi-coin support, and modern memory-safety tooling ckpool does not have.
| Coin | Ticker | Algorithm | Notes |
|---|---|---|---|
| Bitcoin | BTC | SHA-256d | V1, TLS, SV2 |
| Bitcoin Cash | BCH | SHA-256d | CashAddr, V1/TLS/SV2 |
| Bitcoin SV | BSV | SHA-256d | V1/TLS/SV2 |
| Fractal Bitcoin | FB | SHA-256d | V1/TLS/SV2 |
| eCash | XEC | SHA-256d | Avalanche pre-consensus, SV2 |
| DigiByte | DGB | SHA-256d | V1/TLS/SV2 |
| Litecoin | LTC | Scrypt | merge-mines DOGE |
| Dogecoin | DOGE | Scrypt (AuxPoW) | merge-mined on LTC |
| Zcash | ZEC | Equihash 200,9 | mining.set_target, Blossom subsidy |
# system deps
sudo apt update
sudo apt install -y build-essential cmake ninja-build pkg-config git \
libboost-system-dev libboost-thread-dev libboost-program-options-dev \
libssl-dev libpq-dev libpqxx-dev libzmq3-dev libsodium-dev libsecp256k1-dev
# clone + configure + build (C++23)
git clone <your-fork-url> mkpool && cd mkpool
cmake -S . -B build -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo
cmake --build build -j| Option | Default | Description |
|---|---|---|
MKPOOL_BUILD_TESTS |
ON |
Catch2 unit tests |
MKPOOL_ENABLE_LTO |
ON |
Link-time optimization |
MKPOOL_ENABLE_TLS |
ON |
OpenSSL TLS context support |
MKPOOL_ENABLE_METRICS |
ON |
Prometheus exposer |
MKPOOL_ENABLE_ASAN |
OFF |
AddressSanitizer |
MKPOOL_ENABLE_TSAN |
OFF |
ThreadSanitizer |
MKPOOL_ENABLE_UBSAN |
OFF |
UndefinedBehaviorSanitizer |
MKPOOL_ENABLE_NATIVE |
OFF |
-march=native |
cd build
ctest --output-on-failure -jscripts/run_sanitizers.sh builds the unit tests under AddressSanitizer,
UndefinedBehaviorSanitizer, and ThreadSanitizer in a throwaway .san/ directory
(your normal build/ is left untouched) and reports any findings.
./scripts/run_sanitizers.sh # asan+ubsan and tsan
./scripts/run_sanitizers.sh asan # a single flavor
./scripts/run_sanitizers.sh --fuzz # also fuzz a sanitized instancescripts/fuzz_*.sh throw malformed and abusive Stratum traffic at a running
pool and assert it survives (same PID before and after) with no handler
exceptions. Point them at a local instance:
# quick malformed-frame battery
HOST=127.0.0.1 PORT=3331 ./scripts/fuzz_stratum.sh
# full suite: malformed JSON, protocol abuse, share spam, auth abuse,
# slowloris, version-rolling abuse, binary noise
HOST=127.0.0.1 PORT=3331 ./scripts/fuzz_suite.sh- Copy the relevant
config-<coin>-<net>.jsonand fill in real RPC / DB credentials (the pool expects a reachable PostgreSQL instance). Server configs are hand-maintained, never overwrite them with repo templates. ./build/mkpool --config config-btc-mainnet.json
Each running pool exposes:
- Stratum V1: per-coin ports (see config; e.g. BTC
3333, vardiff + fixed tiers). - Stratum over TLS:
stratum+ssl://on the redundant low ports (e.g. BTC3334/3335/3336). - Stratum V2 (Noise): e.g. BTC
3340, BCH3350, ZEC, XEC, FB.
+-----------+ +------------+
bitcoind ZMQ --> | Generator | -- GBT -> | Stratifier |
+-----------+ +------------+
| JobPtr
v
PoolManager (sharded session map)
| notifyNewJob (per-session strand)
v
+-------------------+
miner --> | ClientSession (N) |
V1 / TLS +-------------------+
/ SV2 ^
|
RateLimiter
IoPoolruns N workerio_contexts (default =hardware_concurrency()).- Each
ClientSessionlives on one workerio_contextvia an Asio strand; the socket type (plain / TLS / SV2-Noise) is abstracted behindany_stream. PoolManageriterates shards on eachJobPtrand dispatchesnotifyNewJobto every session's strand.
mkpool is free and open source. There is no fee to use the code and no built-in donation skim. If the project has been useful to you and you would like to chip in toward its development, you can send a tip here. It is entirely optional and very much appreciated.
BTC: bc1qlugz6as6x3n03c6x8zddpnmypsaucdmh3lc5z0
mkpool is built on top of a lot of excellent open source work. A sincere thank you to the maintainers and contributors of every project below. The pool would not exist without them.
| Library | License | Used for |
|---|---|---|
| Boost (Asio / Beast) | BSL-1.0 | Async networking, strands, HTTP RPC client |
| OpenSSL | Apache-2.0 | TLS, SHA-256 |
| fmt | MIT | Hot-path Stratum formatting |
| spdlog | MIT | Logging |
| nlohmann/json | MIT | Config and RPC JSON |
| cxxopts | MIT | Command-line parsing |
| libpqxx / libpq | BSD-3-Clause / PostgreSQL | Database access |
| ZeroMQ (libzmq) | MPL-2.0 | Block-hash notifications |
| libsodium | ISC | Stratum V2 Noise crypto |
| libsecp256k1 | MIT | EC keys / signatures (SV2) |
| Catch2 | BSL-1.0 | Unit tests |
| prometheus-cpp | MIT | Optional metrics endpoint |
All of these are under GPLv3-compatible licenses. mkpool does not vendor (copy)
their source; they are linked from your system package manager or fetched by
CMake at build time. If you distribute a compiled mkpool binary, ship a
THIRD-PARTY-NOTICES file reproducing these projects' copyright and license
texts alongside it.
mkpool is original software, © 2025-2026 Mecanik1337 (contact@mecanik.dev),
licensed under the GNU General Public License v3.0 (GPL-3.0). Every source
file carries the full GPLv3 header.
Almost all of the codebase (the async engine, multi-coin support, Stratum V2 (Noise) and TLS, solo coinbase construction, and security tooling) is written from scratch and owes nothing to ckpool beyond being the same kind of program.
The single exception, disclosed for honesty and license compliance: the
variable-difficulty retarget math in vardiff.cpp /
vardiff.hpp re-implements ckpool's decay_time()
(src/libckpool.c) and time_bias() / add_submit() (src/stratifier.c) by
Con Kolivas (also GPLv3). That is the only part adapted from ckpool; no
ckpool C source files are vendored or copied verbatim, and a few Stratum field
conventions (e.g. 4-byte extranonce1) simply follow common practice. These are
attributed inline. Because mkpool is GPLv3, this re-use is fully permitted; if
you redistribute mkpool, keep it under GPLv3, retain these attributions, and
ship the full license text (COPYING).
ckpool: https://bitbucket.org/ckolivas/ckpool, © 2014-2026 Con Kolivas.