Mining
MatMul proof-of-work mining on the BTX network.
BTX uses MatMul proof-of-work, a mining algorithm based on matrix multiplication. Instead of brute-force hash puzzles, miners perform 512×512 matrix multiplications over a Mersenne prime field and use the computation transcript as the hardness source.
How MatMul mining works
At a high level, each mining attempt proceeds as follows:
- The block header (including nonce) seeds a random oracle that generates two n×n matrices (A and B) over the field Fq where q = 231−1 (Mersenne prime M31).
- The miner computes the product C = A × B using a block-structured algorithm with transcript block size b = 16. Low-rank random noise of rank r = 8 is injected from the random oracle to make the computation transcript unpredictable.
- The intermediate computation transcript is hashed. If the resulting digest meets the current difficulty target, the block is valid.
- Validators can verify the proof efficiently using a two-phase check: a cheap header-level filter followed by transcript recomputation. A Freivalds probabilistic verification step provides fast initial confirmation.
Consensus parameters
| Parameter | Value | Description |
|---|---|---|
| Matrix dimension (n) | 512 | 512×512 matrices, ~2 MiB working set |
| Transcript block size (b) | 16 | Hashing granularity for the computation transcript |
| Noise rank (r) | 8 | Rank of random noise injected per block |
| Field | M31 (231−1) | GPU-friendly int32 Mersenne prime arithmetic |
| Target block time | 90 seconds | Steady-state (post block 50,000) |
| Difficulty algorithm | ASERT (aserti3-2d) | Per-block adjustment from genesis |
| ASERT half-life | 14,400s (3,600s after height 55,000) | Responsiveness parameter |
| Block subsidy | 20 BTX | Halves every 525,000 blocks |
| Supply cap | 21,000,000 BTX | Hard cap |
Hardware requirements
MatMul PoW is designed to leverage the same GPU hardware used for AI/ML training workloads. The core operation (dense matrix multiply over M31) maps directly to GPU tensor cores and matrix multiply units.
| Component | Minimum | Recommended |
|---|---|---|
| GPU | Any with compute capability | AI-training class (NVIDIA A100/H100, Apple M-series with Metal) |
| RAM | 8 GB | 16+ GB |
| Storage | 50 GB SSD | 200+ GB NVMe |
| CPU | 4 cores | 8+ cores (for validation alongside mining) |
CPU-only mining is functional but significantly slower. The Metal backend on Apple Silicon provides competitive throughput for solo and small-scale mining.
getblocktemplate workflow
External miners use the getblocktemplate RPC to obtain a
candidate block, solve the MatMul puzzle, and submit the result with
submitblock.
# Fetch a block template
btx-cli getblocktemplate '{"rules": ["segwit"]}'
# Submit a solved block
btx-cli submitblock "hexdata"
The template exposes the BTX MatMul nonce range:
noncerange = 0000000000000000ffffffffffffffff.
For testing, generateblock with submit=false can
produce candidate blocks without broadcasting, useful for verifying the
miner pipeline.
Mining to a specific address
The simplest way to mine is with generatetoaddress, which
handles template creation, solving, and submission internally:
# Generate 1 block paying to a specific address
btx-cli generatetoaddress 1 "btx1z..."
For production mining, the payout address is typically a post-quantum
multisig descriptor address (btx1z...). Operators should
derive and verify this address offline before starting the miner.
Pool mining
Stratum integration for pool mining is under development. The
getblocktemplate interface provides the foundation for
external pool software. A validation script
(scripts/m7_miner_pool_e2e.py) exercises the full
generateblock submit=false + submitblock
pipeline and captures a stratum job artifact.
Current status: solo mining via generatetoaddress or the
miner daemon loop is the primary production path. Pool operators should
follow the btx-node
repository for stratum protocol updates.
Apple Silicon Metal backend
BTX Node includes a native Apple Metal compute backend for MatMul mining on Apple Silicon (M1, M2, M3, M4 series). Enable it at build time:
cmake -B build-btx -DBTX_ENABLE_METAL=ON
cmake --build build-btx -j$(sysctl -n hw.ncpu) Select the Metal backend at runtime:
export BTX_MATMUL_BACKEND=metal Available backend tokens:
| Token | Description |
|---|---|
cpu | Reference CPU implementation (always available) |
metal / mlx | Apple Metal compute (Apple Silicon only) |
cuda | NVIDIA CUDA (scaffolded, disabled by default) |
Non-Apple hosts or systems without Metal automatically fall back to CPU.
Use btx-matmul-backend-info --backend metal to check backend
availability and capabilities.
Tuning parameters
| Environment variable | Description | Recommended |
|---|---|---|
BTX_MATMUL_SOLVE_BATCH_SIZE | Nonces per GPU dispatch | 4 |
BTX_MATMUL_PIPELINE_ASYNC | Async GPU pipeline | 0 |
BTX_MINE_BATCH_SIZE | Blocks per mining batch | 20 |
Mining in regtest
Regtest mode skips MatMul validation by default
(fSkipMatMulValidation=true), enabling instant block
generation for development and testing:
btxd -regtest -daemon
btx-cli -regtest createwallet "test"
btx-cli -regtest -generate 100 To test with full MatMul validation in regtest, use the strict mode flag:
btxd -regtest -test=matmulstrict -daemon Monitoring with getdifficultyhealth
The getdifficultyhealth RPC provides diagnostics for
difficulty adjustment behavior, chain cadence, and mining readiness:
btx-cli getdifficultyhealth Key fields in the response:
- target_spacing_s: target block interval (90s)
- tip_age_s: seconds since the last block timestamp
- cadence metrics: mean/median/stddev of recent block intervals across configurable time windows
- reorg_protection: deep-reorg protection configuration and rejection counters
The companion monitoring tool
monitor/btx_difficulty_health.py aggregates data from
multiple nodes (local + archival fleet) and produces JSON and Markdown
reports across 1h/6h/24h time windows. Reports automatically exclude
the fast-mine bootstrap phase (blocks 0–49,999) on mainnet.
If tip_age_s exceeds 3× the target spacing while
miners are active, the chain should be considered stalled. Inspect
getchaintips and debug.log for
status=invalid tips.