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 withcmd/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:
- it is at least 0.05 POWM and at least the key’s own
threshold(threshold = 0means the network’s minimum, otherwise 0.05 × 2^threshold POWM), and - 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
addrentry 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
balanceis 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.