Documentation

The Sharepool — a pool built into consensus

Status: in progress. Implemented: shares, their gossip and settlement (§2, §3.1), the pot and the credits (§3.2, §5.1), the payouts (§5.2), the fork choice between siblings (§4), the miner’s shares (solo and through a stratum server) and the miner’s own finality key over stratum (§2.1). Not yet: the signing bonus (§3.3), the wallet’s view (§5.3) and finality v2 (§9). The Sharepool replaces the decentralized pool above consensus (the sharechain design) and changes the quorum of finality. The parameters marked sim were chosen with cmd/powm-sharesim, the verification costs were measured with cmd/mh-bench.

1. What it is for

A small miner either mines solo and waits weeks for a block, or gives its hashrate to a pool that holds its money and decides what it mines. A botnet has neither problem — a hundred thousand bots behave like a pool. Variance is the disadvantage a legitimate small miner has.

The Sharepool removes the operator. A miner publishes shares — proofs of work under a target far easier than a block’s — and the chain itself pays every share. Nobody holds the money, and nobody can be pressured into changing who gets paid.

miners (lane C, lane G)
   │  shares: 100 a second across the network, gossiped like transactions
   ▼
the Sharepool            ← every full node keeps the shares of the last 8 blocks
   │  a block includes the shares it knows about and pays each a fixed price
   ▼
the chain of blocks      ← a block every 30 s; credits in the state, payouts in the coinbase

2. The share

2.1 What is mined

A share is a block header: the same 89 B, the same MachinaHash, nothing in internal/mh changes. What changes is what the header’s fields mean:

field in a share
prev_block the block the share builds on — its vote (§4)
merkle_root BLAKE3("PowMachina/share/v1" ‖ body_root ‖ payout_program ‖ finality_key ‖ threshold ‖ weight)
bits the lane’s block target on prev_block — the same number a block there carries
height prev_block’s height + 1
time, nonce, lane, version as in a block

body_root commits to the block the miner would close: its transactions, its included shares and its coinbase. A share whose hash also meets the lane’s block target therefore is that block — the miner publishes the body and the network checks it against body_root. Nobody can attach a different body to a lucky share afterwards.

payout_program (the 32 B program of a version 0 address), finality_key (zeros = none), threshold (one byte, §5.2) and weight (one byte, §2.2) — the share commitment, 66 B — are under the PoW as well. A block carries the same commitment between its header and its transactions (SPEC §3.2); it is the share that also met the block’s target, and its finality key is the one that gives its miner a seat (finality §2). A share cannot be redirected to another address, which is why mining through a stranger’s node is safe: the node can refuse the work, it cannot steal it.

The same holds for the seat. A miner on somebody else’s stratum logs in with its own finality key (powmachina-miner --finality-key, on by default; the stratum protocol). The blocks it finds carry that key, so their seat in the finality quorum is the miner’s, and the server asks the miner to sign for it (attest). A pool cannot collect the votes of the hashrate it serves; only a miner that turns the key off, or runs software without it, leaves its seat to the server.

2.2 The share target

There is no separate retarget. The lane’s block target sets the share’s, and the share’s weight k makes it 2^k minimum shares:

min_share_work(lane) = block_work(lane) / 3000
share of weight k:     hash < (block_target + 1) × 3000 / 2^k        k = 0 … 11

The header’s bits stay the lane’s block target, checked like a block’s on the same parent, so the retarget, the chainwork and the rules of a block do not change; the weight is in the commitment, under the PoW, so nobody who relays a share can lower it. A block is a share of every weight up to 11, because 2^11 < 3000.

A lane has a block every 60 s and the network 100 shares a second, 50 per lane — 3,000 shares of minimum work per block of the lane. A miner may choose a heavier share (a higher weight); it counts as 2^weight minimum shares (share units, §3). A farm saves bandwidth that way, nobody gains.

Because the work of a share is measured against its own lane’s block, a share unit of lane C and one of lane G are worth the same. The lane parity of the chain carries over into the payouts with no coefficient.

Why 100 a second (sim, rate): a device holding 1/N of a lane gets per day

devices per lane shares a day spread of a day’s reward
10,000 432 ±4.8 %
100,000 43 ±15 %
1,000,000 4.3 ±48 %

Monero’s P2Pool, for comparison, has 0.1 shares a second. The cap is set by what a node can verify and store: a share costs a full node 4.9 ms (lane C) or 1.5 ms (lane G), a light node 35 ms and 98 ms. At 100 a second a full node with four cores spends about a quarter of one core on it. Shares are verified only by full nodes (§7).

2.3 On the wire

A share travels compactly, in the shares message (internal/p2p/wire_cshare.go). Each side of a connection keeps two dictionaries that the sender fills, and an entry is sent once:

item fields bytes
a key tag, number (4), payout_program (32), finality_key (32) 69, once per miner
a job tag, number (4), the key’s number (4), lane, threshold, version, bits, height, a base time (4 each), prev_block (32), body_root (32) 91, once per template
a share tag, the job (2, the low bits of its number), nonce (8), time (2, a delta from the job’s), weight (1) 14

The merkle root is not sent — the receiver computes it from the body root and the commitment, so a compact share cannot carry a root that does not match. The job carries the parent because a template is built on one: the body root already depends on it. Numbers go up by one on each side, the receiver keeps the last 4,096 keys and jobs (≤ ~630 kB a connection) and the sender defines an entry again once it is older than that; an entry out of order is a bad message. A node collects the shares for a peer for 100 ms and sends them as one message — the frame alone is 24 B.

A share of a farm costs 14 B; a small miner who changes its template more often than it finds a share pays the job too, ~105 B. A miner hands its shares to its node with submitshare in full (187 B). A node relays a share only after it has verified its PoW; a peer that sends an invalid one is banned. A share whose prev_block is more than 8 blocks below the tip is not relayed.

3. Settlement

3.1 Including shares

A block includes the shares it knows about that are not yet included on its branch and not older than 8 blocks: a share’s prev_block has to be one of the 8 blocks below the new block on the new block’s own branch (1 = its parent). The shares travel with the block as its settlement body (§6), and a full node accepts the block only when every share in it is valid and none is included twice on the branch — nor is a block of the branch, which was paid as the block it is.

A share that built on a sibling that lost is not paid: checking it would take the sibling’s header in the body, and what is lost that way is the few seconds a fork lasts. A share that built on the winner, or on the block both siblings share, is paid either way.

The settlement body is three tables (internal/chain/settlement.go):

bytes
a key — payout_program, finality_key 64, once per miner
a job — key, lane, threshold, weight, version, body_root 41, once per template
a share — job, depth (1–8), time, nonce 15

A share’s header is rebuilt from them and from the branch — its parent is the block depth below, its bits the lane’s on that parent — and its PoW and id are checked as if it had come whole. The time is four bytes, not a delta: a chain that stood still for hours would have shares a two-byte delta cannot express. The encoding is canonical: every entry is used, the tables are in the order of first use, the shares in the order of their ids. A block’s body_root covers the transactions and the settlement body, so a share commits to the shares its block would pay. Caps: 12,000 shares (four blocks’ worth, so a block can pick up what a censor left out) and 256 kB, apart from the 96 kB of transactions.

Why 8 blocks (sim, censor): a closer may leave other miners’ shares out. With an expiry of two blocks the honest shares a censor leaves out run out before anybody includes them — at 45 % of the hashrate that is a fifth of the honest work, and censoring pays. With eight the left-out shares are simply included by the next honest block: the honest network loses under 0.1 %, and the censor earns 0.99 of its fair share — less than when it is honest.

3.2 The reward rule

Every block’s reward goes into a pot, and a block pays each share unit it includes a price that does not depend on how many it includes:

pot          += subsidy − dev fee + transaction fees        (every block)
price         = pot / (16 × 3000)                           per share unit, both lanes alike
paid(block)   = min(pot, price × units included)
pot          −= paid(block)

The rule a pool would use — a block splits its whole reward over the shares it includes — pays a censor 1.4–1.8 times its fair share (sim, censor): leaving everybody else out makes its own shares worth more. A fixed price makes leaving shares out worthless. What a block does not pay stays in the pot for the shares that come later.

The pot holds about 16 blocks of reward (8 minutes) at rest; it is what smooths the payout over lucky and unlucky blocks. The emission does not change: every cog of the subsidy goes through the pot, only later. Integer arithmetic, the remainder of the division stays in the pot.

The units a block pays are its settlement’s shares and its own share — the block is the share that also met the block’s target, 2^weight units of the commitment it carries. When a block settles more units than price × units the pot covers, the pot is split in proportion (pot × units_i / units, rounded down). The transition is one function, chain.CreditStep.

The dev fee stays the coinbase’s first output, 5 % of the block’s subsidy (SPEC §2.1); it never enters the pot. Transaction fees go into the pot, not to the closer: a closer that kept the fees would have a reason to orphan a sibling block (§4).

3.3 The signing bonus

Of the price, 5 % is paid only to keys that sign the finality checkpoint (§9):

  • a key with a seat in the quorum gets the 5 % for a share unit only if its attestation of the last checkpoint is in the chain; what it does not get goes to the keys with a seat that signed,
  • a key without a seat (below the weight a seat needs) gets the 5 % as if it had signed — a small miner cannot sign and must not lose for it.

A pool that mines and does not sign loses 5 % of its reward, the others gain it. A miner on a stratum server signs for its own seat (§2.1), so the bonus follows the miner, not the server. The bonus does not come from the dev fee and does not change the emission. That is what makes a silent seat, the weak spot of the current finality, expensive (sim, payouts/signing: the loss is exactly the bonus).

4. Choosing between two blocks

Two blocks at the same height on the same parent happen whenever two closing shares are found within the propagation time. Every later share builds on one of them — it votes.

The rule: a node prefers the sibling with the lower block hash, unless the other leads by more than 1,000 share units of votes in what the node has seen. Between branches of different length chainwork decides as usual; MESS and finality stay on top.

Why not “more votes wins” (sim, balance): with the network split into two halves one second apart, a miner with a quarter of the hashrate keeps the fork open for as long as it likes by giving its votes to whichever half is about to switch — the settlement and finality stand still. With a tie-break both halves agree as soon as they have seen both blocks, at any share of the attacker up to 45 %. The margin has to be larger than the share rate × the worst latency between parts of the network: 300 failed at 10 s, 1,000 holds there. 1,000 is a third of a block’s shares.

What it costs: a closer that holds its block back for a few seconds wins against an honest sibling half the time (when its hash is lower). It gains nothing by it — the reward goes to shares, which carry over (§3.1), and the fees to the pot — so the cost is a one-block reorg, not a profit.

In the node (internal/chain/siblings.go): the block hash is the block ID, a vote is a share in the node’s share pool built on the sibling, worth its units (2^weight). The rule is a node’s preference, not a validity rule. A light node holds no shares and simply prefers the lower ID; after a restart a full node does the same until shares come in. A share that tips the balance moves the tip at once, through the same path as any reorg.

5. Credits and payouts

5.1 Credits

What a block pays a share is not an output, it is a credit of the share’s payout_program in the chain’s state (internal/chain/credits.go). An entry is payout program → amount, threshold (of the key’s last settled share), the height of its last share, of its last payout, and the height at which the amount last reached what its threshold asks for; the state also holds the pot.

Its root goes into the coinbase’s commitment output as "PMcr" ‖ root after the witness root (SPEC §3.2): BLAKE3("PowMachina/credits/v1" ‖ pot ‖ tree), where the tree is a sparse Merkle tree keyed by the payout program bit by bit — an empty subtree is 32 zero bytes, a subtree with one entry is that entry’s leaf BLAKE3("PowMachina/credit/leaf/v1" ‖ program ‖ entry), any other is BLAKE3("PowMachina/credit/node/v1" ‖ left ‖ right). A block commits to the state its parent left: the coinbase then depends on nothing its miner chooses, and a light wallet checks its credit against the next block’s root. The node recomputes the root from the whole state (§10).

5.2 Payouts

A credit is paid out by the coinbase, as an ordinary version 0 output, when:

  1. it is at least 0.05 POWM and at least the key’s own threshold (threshold = 0 means the network’s minimum, otherwise 0.05 × 2^threshold POWM), and
  2. the key was paid more than 2,880 blocks (24 h) ago.

The order is fixed: the credits that became payable earliest first — the later of the height the credit reached its threshold and the end of its key’s day — a tie broken by the payout program. A coinbase pays the queue from the front for as long as the storage mass reserve (16,000) and 400 outputs last. It must pay exactly the front of the queue, the whole credit of each key; a coinbase that skips someone is invalid. The queue is that of the state the block builds on, so the payouts come before the block’s own credits.

Why once a day (sim, payouts): paying whenever a credit crosses the minimum pays the big keys every block — ~640,000 outputs a day already at 1,000 keys, and at 100,000 keys the queue is two hours long. Once a day at 100,000 keys is ~92,000 outputs (3.9 MB) a day, nobody waits in the queue, and the smallest tenth of the miners is first paid within ~1.6 days. About a day of emission sits as credit.

A payout matures like any coinbase output (§8). A key without a share for 90 days is paid whatever it has above the dust limit; below it, the credit returns to the pot.

5.3 What a wallet shows

state where it is spendable
unsettled shares in the Sharepool, not in a block yet — an estimate no
credit in the chain’s state, below the minimum or waiting for its day no
maturing paid out, the coinbase not mature no
available an output yes

A wallet shows one number — available — and under it a line on its way with the rest. RPC: getcredit <address|key> and getsharestats <key> on the node; the wallet’s getbalance keeps its fields and adds credited, maturing, unsettled_estimate.

In the explorer (/explorer/shares): the node’s share pool by miner (getsharepool), and on a block’s page who closed it and who its shares paid (getblock → settlement). Every miner has an icon and a colour drawn from its payout program (internal/identicon: a 5×5 mirrored grid from SHA-256, nothing stored or sent), so the pool and a block read as a mosaic of who mines. The wallet can draw the same icon from the same program.

Live (/explorer/api/sharepool, JSON, cached 2 s): the pool, the last 16 blocks with who closed them and whom they paid, the last 60 blocks summed (miners, shares, units, how many miners were paid out) and the ten miners with the most units in them, each with its credit and what its payout needs (getcredits). /explorer/api/sharepool/miners (cached 15 s) is every miner of those 60 blocks with its icon. The Sharepool page of this website draws the flow from both.

Where the shares come from (getsharegeo, in the live answer as geo): a node started with -geoip <DB-IP country CSV> counts, for every share it takes first, the country of the address it came in from — the stratum device, or the peer that relayed it — per minute over the last 30 minutes, and since its start. It is the country of the miner’s node or of a node on the way, not a statement about the miner; a private or local address is unknown. No address is stored, and no country is tied to a payout address.

6. Data

per day kept by
headers and coinbases ~1 MB everybody
transactions up to ~210 MB at full blocks (72 kB of a 96 kB block, §8) everybody, prunable
payout outputs ~4 MB at 100,000 keys everybody
settlement bodies 120–430 MB (14–50 B a share) full nodes until the block is final, archival nodes for ever

A settlement body is needed to verify a block and to recompute the credits, not to use the chain. A full node prunes it once the block is final. A new full node syncs either from an archival node or from a credit snapshot at a final checkpoint, verified against the root in the coinbase.

7. Nodes

RAM verifies shares relays shares
full node — miners, pools, exchanges, seeds 8 GB recommended (~3.5 GB: the RandomX dataset 2.1 GB + the DAG 1 GiB, the DAG grows 4 MiB a week; ~6.5 GB for the ten minutes around an epoch boundary, when the next epoch is built before the old one is let go) yes yes
light node 1 GB no — it checks the closing share’s PoW and takes the settlement on trust, like SPV no
archival node full + disk yes yes, and serves settlement bodies

Which one a node is follows from its DAG: a node holding the full DAG (-dag=full, or -dag=auto while it catches up) verifies, pools and relays shares, and its templates settle them; one running light (-dag=light, or -dag=auto at the tip) refuses submitshare, relays none and takes the PoW of a block’s shares on trust while checking everything else. A miner’s or a pool’s node runs -dag=full.

8. Parameters at a 30 s block

The emission and every rule measured in time keep their values in time; whatever is counted in blocks is sized for a 30 s block.

value note
BlockTime / LaneBlockTime 30 s / 60 s
InitialSubsidy 10 POWM
HalvingInterval 4,200,000 ≈ 4 years; the halvings sum to 84 M
SlowStartBlocks 20,000 ≈ 7 days
DevFeeEndHeight 2,100,000 ≈ 2 years, 5 % of the subsidy
TailSubsidy 0.24975 POWM 0.999 POWM every 2 minutes
CoinbaseMaturity 400 (≈ 3.3 h), or the block is final (§9)
ReorgLimit 2,000 ≈ 16.7 h
EpochBlocks 20,000 ≈ 6.9 days
FinalityDepth / FinalityWindow 80 / 2,880 40 min / a day
SignalWindow 4,000
LaneWindows (metrics) 40, 160, 320, 480
the chainwork normalization window 1,440 12 h; an average of the lanes’ difficulty needs hours, and a sync walks it for every header
MaxBlockBytes 96 kB + the settlement body transactions: about 2.1 kB/s
MaxCoinbaseBytes 24 kB 400 payouts × 43 B + the commitments
MaxBlockStorageMass 64,000, of it 16,000 for the coinbase
the retarget 60 s pace, half-life 1 h, 16× per gap the spread at rest is about 7 %
LaneRotationRelief 300 s 5 lane blocks; see below
MedianTimeSpan, MaxFutureDriftStrict 11, 30 s see below
MESS, the mempool, orphans in seconds

The relief and the drift (go run ./cmd/powm-diffsim -spacing 60 -relief N, 50 runs, the chain’s rule asert-1h-cap4):

relief third block of a lane at rest chain, one lane dead other lane’s ease, 99 % of a lane gone
150 s 0.66 % 210 s 1.67×
225 s 0.13 % 285 s 1.90×
300 s 0.03 % 360 s 2.25×
450 s 0 509 s 2.79×
900 s 0 958 s 4.66×

300 s rarely lets a third block of a lane through, keeps a chain with one lane gone at a block per 6 minutes, and leaves 270 s of it that a block dated 30 s ahead cannot take away. Backdating stays shut at every value (a lane at 30 % backdaters runs at 60 s), because a block is not dated before its parent. The drift stays 30 s: a block dated that far ahead makes a lane look 30 s late, which eases it by 2^(30/3600), 0.6 %.

The specification carries the same values.

9. Finality v2

The quorum is now the finality keys of the blocks of the last 2,880 (finality). Finality v2 makes it the share work of the last day (2,880 blocks) per finality_key, each lane half of the weight — a quorum of thousands of samples instead of hundreds, so a key’s weight follows its hashrate within hours. Since a miner on a stratum server mines under its own key (§2.1), its share work is its own weight in the quorum, not the server’s.

  • A seat needs 0.5 % of the weight. At most 200 keys sign; a checkpoint of 200 attestations is ~13 kB. Below it a key mines and is paid, it just does not sign (§3.3).
  • A checkpoint every 4 blocks (2 min), signed at a depth of 80.
  • No aggregate signature. 200 Ed25519 signatures every 2 min are ~9 MB a day; an aggregate would need a dependency outside the standard library. It can come later without a change to what is signed.
  • Attestations go into the chain — a later block’s settlement body carries them. Finality stops being something a node had to see; it is in the blocks, which is what the signing bonus and a payout maturing at finality need.
  • Attestations for a final height are still taken, checked for a double signature and relayed. The node does not do that yet — it drops them (internal/chain/finality.go), so a key that signed both sides of a split is never caught.

10. What is open

  • A full node that does not listen hears no shares. Shares travel between full nodes only (§7), and full nodes find one another through address gossip: every addr entry carries the services it was seen with, a full node fills its first outbound slots with full-DAG peers and swaps a light peer for one when it learns of it (cmd/powmachinad/addrgossip.go). That needs full nodes others can dial: the network needs full nodes (8 GB) that listen on a public address. The public testnet has them.
  • The credit root is recomputed from the whole state for every block, once to apply it and the payout queue once more to validate and once for the template: measured on an 8-thread workstation, the root takes 0.12 s at 100,000 keys and 1.3 s at a million, a whole credit step 0.17 s at 100,000. Fine for a testnet, not for a mainnet that hopes for a million miners — a cached tree that rehashes only the paths a block touched gives the same root, and the queue wants an index ordered by when a credit becomes payable.
  • Compact blocks. A block is pushed whole (~50 kB with 3,000 shares); its peers already have the shares, so the settlement could travel as ids.
  • The settlement body and pruning in practice — the credit snapshot sync is new code.
  • An empty block costs a closer nothing and a full one earns it little, because the fees go to the pot. If miners start closing empty blocks, a part of the fees goes to the closer — at the price of a reason to orphan siblings (§4).
  • The simulator’s limits: the race between two blocks is modelled, not run on a network; the topology is two halves; the attacker in balance is greedy, not optimal. A testnet with several independent miners is the real test.

11. What came before

Each piece exists; the combination does not, as far as we found:

  • FruitChains (Pass, Shi 2017) — near-blocks paid from the coinbase. Stouka and Zacharias (2023) argue pools persist anyway because miners share the cost of assembling the work; here mining through a stranger’s node is safe (§2.1), which removes that cost.
  • Tailstorm (Keller et al. 2023) — a block confirmed by k subblocks, rewards discounted by the shape of the tree; the closest to a block built from shares.
  • Parallel PoW with DAG-style voting (Keller 2023) and HotPoW (Keller, Böhme 2019) — votes and finality from PoW quorums, simulations only.
  • Monero P2Pool and Braidpool — share chains above consensus.