§ 09

§ 09 · Difficulty

WTEMA

The rule that retunes the difficulty after every single block

Think of cruise control on a hilly road. It doesn’t wait ten minutes and then slam the pedal. It feels every small slowdown and eases the throttle a little, all the time.

Pearl’s difficulty works the same way. After every block, every node looks at how long that block took, compares it with 194 seconds, and nudges the target: a little easier if the block was slow, a little harder if it was quick. The rule is called WTEMA, short for “weighted-target exponential moving average”.

Each nudge is tiny. Together they hold the pace near one block every 194 seconds, whatever the miners do.

Try it

Make the mining power jump or crash, and watch block times and the target react, block by block. Compare it with Bitcoin’s once-every-2,016-blocks rule.

WTEMA simulator

Hashrate jumps; the target follows, a little after every block

Simulation Blocks arrive at random, as on the real network, but the hashrate and timeline are made up. Times are random draws, not chain data.

Demo run · Block 8,064 of 8,064 day 17.1 WTEMA avg 232 s · diff ×1.15 Bitcoin-style avg 272 s · diff ×1.36

After 8,064 blocks: hashrate ×1.00. WTEMA: last 144 blocks averaged 232 s, difficulty ×1.15. Bitcoin-style: 272 s, difficulty ×1.36.

This demo doubles the hashrate at block 1,500 and drops it back at 5,000. WTEMA starts correcting with the very next block and closes the gap smoothly, about 63% of it per week of clock time (its one-week time constant). The 2,016-block rule does nothing until its window ends, then jumps all at once, and lags again when the hashrate changes back: blocks run slow until its next window ends.

One step, exactly as pearld does it

The chart uses floating point for speed. pearld uses whole numbers: new target = old + ⌊(t − 194) × old ÷ 604,800⌋, clamped to [1, PowLimit], then rounded into bits.

old target
0x6af3a60000000000000000000000000000000000000000
t − T
300 − 194 = 106 s
adjustment
⌊106 × old ÷ 604,800⌋ = 0x4cc76689133bde689133bde689133bde689133bde68
new target
0x6af87276689133bde689133bde689133bde689133bde68
next bits
0x176af3a6 → 0x176af872
difficulty
40,157,376.49334089 → 40,150,342.21117200 (-0.0175%)

Slower than 194 s, so the target rises a little: the next block gets slightly easier. One block moves it by a fraction of a percent, but the steps compound: if blocks run late by 604,800 seconds in total (one week), the target grows by a factor of about e ≈ 2.72.

Runs in your browser · simulated, not chain data src/lib/wtema.ts · T = 194 s, τ = 604,800 s

What is the rule?

Call the previous block’s target X and its solve time t: its timestamp minus its own parent’s. The next block’s target is

Xnext=X+⌊(t−194)⋅X604,800⌋X_{\text{next}} = X + \left\lfloor \frac{(t - 194) \cdot X}{604{,}800} \right\rfloor
WTEMA, exactly as pearld computes it
Then clamped to the limit 2²⁰⁸ − 1 (and to at least 1), and re-encoded as compact bits, which keeps only the top three bytes.

In words: every second the last block ran late grows the target by one part in 604,800. Every second it ran early shrinks it by the same. A block right on 194 seconds changes nothing.

Those two numbers are Pearl’s parameters: TargetTimePerBlock = 3 minutes 14 seconds, and WTEMAHalfLife = 168 hours, one week.

A worked example with real numbers

Start at the chain tip on 20 October 2026: block 130,827, bits 0x176af3a6. Suppose the next block takes 300 seconds. Pearl’s own code gives:

  1. Decode the old target

    0x176af3a6 → 0x6af3a6 × 2¹⁶⁰ = 10,243,942,661,363,391,425,244,085,692,626,643,778,542,165,820,901,949,440.

  2. Compute the adjustment

    (300 − 194) × old ÷ 604,800, rounded down = 1,795,400,003,479,694,925,720,689,622,054,272,884,466,715,570,462,312.

  3. Add it

    New target = 10,245,738,061,366,871,120,169,806,382,248,698,051,426,632,536,472,411,752: the old one × 1.00017526.

  4. Re-encode as bits

    Keep the top three bytes: 0x176af872. Difficulty goes from 40,157,376.49 to 40,150,342.21.

Here are five steps in a row from the same start, again computed with Pearl’s code:

Step Bits before Solve time Bits after Difficulty after
1 0x176af3a6 194 s 0x176af3a6 40,157,376.49
2 0x176af3a6 194 s 0x176af3a6 40,157,376.49
3 0x176af3a6 300 s 0x176af872 40,150,342.21
4 0x176af872 60 s 0x176af260 40,159,244.31
5 0x176af260 1,000 s 0x176b16dc 40,105,799.40

Which block’s time counts?

The parent’s. A block’s required bits depend only on its parent’s bits and its parent’s solve time, its timestamp minus the grandparent’s. Its own timestamp plays no part. That’s a one-block lag.

Here are six real consecutive blocks. Feed each parent’s bits and solve time into the formula and you get exactly the bits the chain carries:

Block Parent’s bits Parent’s solve time Bits Matches the formula
130,822 0x176adad6 204 s 0x176adb49 yes
130,823 0x176adb49 29 s 0x176ad3d2 yes
130,824 0x176ad3d2 29 s 0x176acc5b yes
130,825 0x176acc5b 295 s 0x176ad0eb yes
130,826 0x176ad0eb 510 s 0x176adf34 yes
130,827 0x176adf34 646 s 0x176af3a6 yes

One consequence: two competing blocks at the same height, built on the same parent, always need exactly the same bits. That matters for choosing between branches.

Why is the “half-life” really a time constant?

The code calls 604,800 seconds WTEMAHalfLife, but its own comment calls it “the time constant for the WTEMA exponential filter”. The comment is right: it behaves as a time constant, not a half-life.

Each block moves the target by a factor (1 + (t − 194) ÷ 604,800). Multiply many of those together and the result is close to

XlaterXnow≈e(total lateness)/604,800 s\frac{X_{\text{later}}}{X_{\text{now}}} \approx e^{\,\text{(total lateness)} / 604{,}800\ \text{s}}
Total lateness = the sum of (t − 194) over the blocks in between.

So one full week of accumulated lateness grows the target by e ≈ 2.72, not 2. It doubles after ln 2 ≈ 0.693 weeks: about 4.85 days of total lateness. The genesis message’s “WTEMA 3m14s 7d” names the same two parameters: 194 seconds and seven days.

Pearl’s code confirms it. With every block 388 seconds apart (each 194 seconds late), after 2,161 blocks, 4.85 days of lateness, the target has grown ×1.96. Without rounding it would be ×2.00.

Are there limits on a single step?

No clamp in the formula. Two other rules bound it instead:

  • Tightening is capped by the timestamp rule. A block must be at least 1 second after its parent, so t ≥ 1 and the biggest single drop is ×(1 − 193 ÷ 604,800) = ×0.99968. Difficulty can rise at most about 0.032% per block.
  • Loosening has no cap except the limit 2²⁰⁸ − 1. A block found a full week after its parent roughly doubles the target (×1.99968). The 5-minute future limit stops a miner from faking that.

The tightening cap explains Pearl’s slow start. Even with every block 1 second apart, climbing from difficulty 1 to 40 million takes at least about 54,857 blocks.

Does rounding matter?

A little, and always in the same direction. The division rounds down, and re-encoding as bits rounds down again, keeping only the top two or three bytes of the target. Both push the target smaller, so difficulty drifts slightly up.

You can see it at mantissa 0xfffe, where one unit of the mantissa is a big step (1 ÷ 65,534 of the target):

Bits before Solve time Bits after
0x1b00fffe 193 s (1 s early) 0x1b00fffd, down one unit
0x1b00fffe 195 s to 203 s 0x1b00fffe, unchanged
0x1b00fffe 204 s (10 s late) 0x1b00ffff, up one unit

One second early knocks the target down; it takes ten seconds late to push it up. At today’s mantissa 0x6af3a6, a unit is 1 ÷ 7,009,190 of the target and one second moves it by about 11.6 units, so the bias is tiny.

The bias grows when the mantissa is small. In the 388-second test above, after 3,118 blocks the target had grown ×2.644 instead of the ideal ×2.718: once the growing target pushed the exponent up a step (to bits like 0x1800d1a7), the compact form kept only about two significant bytes for the rest of the run.

How did it behave at launch?

There was no special start-up mode. Genesis used the easiest bits, 0x1b00ffff; block 1 reused them, and WTEMA ran from block 2.

The first blocks came as fast as the rules allow: blocks 1 to 5 are exactly 1 second apart. Each one tightened the target by the maximum step (block 2 got 0x1b00ffea, block 3 0x1b00ffd5). From there, the climb:

Block Difficulty
2,015 1.93
10,000 23.9
20,000 548
50,000 1.32 million
71,934 17.8 million
130,827 (20 Oct 2026) 40,157,376

Blocks reached about 194-second spacing around blocks 70,000 to 80,000, in early June 2026. On 20 October 2026 the average over the last 144 blocks was 174.3 seconds, a little faster than target. WTEMA reacts over days, not instantly, so while mining power keeps growing, blocks tend to run a little fast. The live average is 174.3 seconds.

How is this different from Bitcoin?

Difficulty adjustment
Topic Bitcoin Pearl
When Once every 2,016 blocks (about two weeks) After every block
Measures Time taken by the last 2,016 blocks Time taken by the last block
Step size Up to ×4 or ÷4 at once One part in 604,800 per second off target
Clamp ×4 / ÷4 per period None; t ≥ 1 s caps tightening at ×0.99968 per block
Reaction to a hashrate shock Nothing until the period ends, then one jump Smooth, halfway in about 4.85 days
Target spacing 600 s 194 s
Code: one WTEMA step in pearld and in JavaScript

From calcNextRequiredDifficulty (node/blockchain/difficulty.go:84-149 at v1.5.2, on GitHub). big.Int.Div is Euclidean division, which for a positive divisor rounds toward minus infinity, so early blocks round the target down too:

node/blockchain/difficulty.go Go
t := lastNode.Timestamp() - parentNode.Timestamp()
T := int64(c.ChainParams().TargetTimePerBlock / time.Second)   // 194
halfLife := int64(c.ChainParams().WTEMAHalfLife / time.Second) // 604,800
oldTarget := CompactToBig(lastNode.Bits())
adjustment := new(big.Int).Mul(big.NewInt(t-T), oldTarget)
adjustment.Div(adjustment, big.NewInt(halfLife))
newTarget := new(big.Int).Add(oldTarget, adjustment)
// clamp to PowLimit, and to at least 1, then:
newTargetBits := BigToCompact(newTarget)

The same in JavaScript with BigInt, plus a floor that works for negative numbers:

JavaScript
const floorDiv = (a, b) => (a % b !== 0n && (a < 0n) !== (b < 0n) ? a / b - 1n : a / b);
const next = (oldTarget, t) => oldTarget + floorDiv(BigInt(t - 194) * oldTarget, 604800n);
Edge cases: other networks and the checkpoint sanity bound
  • Testnet and testnet2 let a block drop to the easiest bits if it arrives more than 4 hours after its parent. The code panics if that option is ever switched on for mainnet.
  • Regtest and simnet never retarget. Signet uses the mainnet rule.
  • Before a block is fully checked, pearld compares its claimed bits with the last checkpoint: over a duration D, the target may have grown by at most (87/32) per started week, (87/32)^⌈D ÷ 1 week⌉. calcEasiestDifficulty (node/blockchain/difficulty.go:151-212 at v1.5.2, on GitHub) uses 87/32 = 2.71875 as a safe stand-in for e. It replaces btcd’s “×4 per two weeks”.

The codex

Suggested

Up and down arrows move through the results, Enter opens one, Escape closes. Anywhere on the site, slash or Command K opens this search, and the square brackets [ and ] go to the previous and next page.