Skip to content

Mecanik/mkpool

mkpool - Modern Multi-Coin Solo Mining Pool

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.


mkpool vs ckpool: Feature Comparison

Legend: ✅ supported · ⚠️ partial / conditional · ❌ not supported

Protocols & encryption

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

Coins, algorithms & merge mining

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)

Pool engine & architecture

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)

Difficulty & share handling

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]) ⚠️ single mindiff/maxdiff
Fixed-difficulty tiers (one TCP port each) ✅ e.g. 10M / 50M / 100M ports ⚠️ via separate instances
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 ⚠️ relies on bitcoind

Security & operations

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.


Supported coins at a glance

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

Build (Ubuntu 24.04+)

# 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

CMake options

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

Run tests

cd build
ctest --output-on-failure -j

Sanitizer sweeps

scripts/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 instance

Fuzz the Stratum parser

scripts/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

Run

  1. Copy the relevant config-<coin>-<net>.json and fill in real RPC / DB credentials (the pool expects a reachable PostgreSQL instance). Server configs are hand-maintained, never overwrite them with repo templates.
  2. ./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. BTC 3334/3335/3336).
  • Stratum V2 (Noise): e.g. BTC 3340, BCH 3350, ZEC, XEC, FB.

Architecture

       +-----------+        +------------+
bitcoind  ZMQ -->  | Generator | -- GBT -> | Stratifier |
       +-----------+        +------------+
                                  | JobPtr
                                  v
                            PoolManager (sharded session map)
                                  | notifyNewJob (per-session strand)
                                  v
                          +-------------------+
                miner --> | ClientSession (N) |
                 V1 / TLS  +-------------------+
                 / SV2            ^
                                  |
                              RateLimiter
  • IoPool runs N worker io_contexts (default = hardware_concurrency()).
  • Each ClientSession lives on one worker io_context via an Asio strand; the socket type (plain / TLS / SV2-Noise) is abstracted behind any_stream.
  • PoolManager iterates shards on each JobPtr and dispatches notifyNewJob to every session's strand.

Support the project

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


Acknowledgments

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.


Attribution & License

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.

Releases

No releases published

Sponsor this project

 

Packages

 
 
 

Contributors