§ 07

§ 07 · Blocks

Time

A Unix timestamp that must move forward by at least a second

Every header says when its block was made. The time is written as a Unix timestamp: the number of seconds since midnight UTC on 1 January 1970.

The miner fills it in, so it’s a claim, not a measurement. Nodes don’t trust it blindly: they only accept times inside a narrow window. Pearl’s window is much tighter than Bitcoin’s, because Pearl retunes its difficulty after every block using these very timestamps.

Try it

The converter starts at 1,792,513,562, the time of block 130,827. Its hex is 6ad7961a, and its 4 bytes in little-endian order are the ones stored in the header.

Hex converter

Decimal, hex and binary, and the bytes in both orders

Big-endian as written
6ad7961a
Little-endian as stored
1a96d76a
Runs in your browser · nothing is sent src/lib/bytes.ts

What does it look like?

Size
4 bytes
Type
Unsigned integer (Unix seconds)
Format
Little-endian
Range
0 to 4,294,967,295 (until the year 2106)
Block 130,827 · header 108 bytes
00000020 999c961b04d94b8b21134e862dc31d5fa56cf9d1f027adb2a0cf95c6525c55eb 6389faa36bd9daffdefc800dea88ac3ef5af1198f7d7179ef3b904420c1cc2c6 1a96d76a a6f36a17 4d52a3fd32160cb032e22edf76912f67dfb1b88946a215281f203836c77ae649
Field Bytes Value
Version header.version 4 @0 0x20000000 int32 LE. BIP-9 style 0x20000000 since block 1; no consensus meaning in Pearl.
Previous block header.prevBlock 32 @4 eb555c52c695cfa0b2ad27f0d1f96ca55f1dc32d864e13218b4bd9041b969c99 Hash of the parent block, stored byte-reversed; shown in display order.
Merkle root header.merkleRoot 32 @36 c6c21c0c4204b9f39e17d7f79811aff53eac88ea0d80fcdeffdad96ba3fa8963 Root of the SHA256d Merkle tree of this block’s txids, stored byte-reversed.
Time header.timestamp 4 @68 1792513562 (2026-10-20 16:26:02 UTC) uint32 LE Unix seconds. Must be at least 1 s after the parent and at most 5 min in the future.
Bits header.bits 4 @72 0x176af3a6 Compact target. Difficulty 40157376.49334089. The certificate's jackpot hash (not this header's hash) must meet it.
Proof commitment header.proofCommitment 32 @76 49e67ac73638201f2815a24689b8b1df672f9176df2ee232b00c1632fda3524d SHA256d(LE32(certificate version) ‖ public data). Replaces Bitcoin’s nonce: Pearl headers have no nonce.
Block hash
1df2f2c1bf39b1a444e622c1788c11736da2f91f4e9a875a38dc23063c6d45b9
Height
130,827
Time
2026-10-20 16:26:02 UTC
Difficulty
40,157,376.49

Bytes 68 to 71 of block 130,827 are 1a 96 d7 6a. Read little-endian, backwards, that’s 0x6ad7961a:

𝟶𝚡𝟼𝚊𝚍𝟽𝟿𝟼𝟷𝚊=1,792,513,562 s⇒2026-10-20 16:26:02 UTC\texttt{0x6ad7961a} = 1{,}792{,}513{,}562 \text{ s} \;\Rightarrow\; \text{2026-10-20 16:26:02 UTC}

Whole seconds only, no time zone: it’s always UTC. And because the field is an unsigned 32-bit number, it runs out in the year 2106, as Pearl’s code comment notes.

What are the rules?

Two, one on each side:

Pearl's timestamp window
Field Size Description
Lower bound — At least 1 second after the parent's timestamp. Anything earlier fails with ErrTimeTooOld.
Upper bound — At most 5 minutes past the node's network-adjusted time. Anything later fails with ErrTimeTooNew.

Pearl’s own code was run on the edges to confirm them:

Timestamp Result
Same second as the parent rejected, too old
Parent + 1 s accepted
Node’s adjusted time + 5 min 0 s accepted
Node’s adjusted time + 5 min 1 s rejected, too new

“Network-adjusted time” is the node’s own clock, corrected by the median offset reported by its peers (offsets beyond ±70 minutes are ignored), the same logic btcd uses.

Why so strict?

Because of how Pearl sets its difficulty. Bitcoin looks at time once every 2,016 blocks. Pearl’s WTEMA rule looks after every block: the next block’s target is nudged according to how long the last block took, its timestamp minus its parent’s.

  • The 1-second rule keeps that gap positive. The code comment says it plainly: the rule is “required for WTEMA difficulty adjustment”.
  • The 5-minute rule limits how far a miner can bend a gap by lying about the time. One week of lateness changes the target by a factor of about e, so 5 minutes of fake lateness moves the next target by only about 300 ÷ 604,800 ≈ 0.05%, and the next honest timestamp gives it back.

The details of WTEMA are in WTEMA and timestamps.

What do real Pearl timestamps look like?

A few landmarks, straight from the chain:

Block Timestamp UTC
0 (genesis) 1,777,280,400 2026-04-27 09:00:00
1 1,777,280,401 2026-04-27 09:00:01
120,000 1,790,541,786 2026-09-27 20:43:06
130,825 1,792,512,899 2026-10-20 16:14:59
130,827 1,792,513,562 2026-10-20 16:26:02

Blocks 1 to 5 are exactly one second apart: at launch, difficulty was at its minimum and miners found blocks as fast as the rule allows. Since then WTEMA has pulled the pace toward the 194-second target. Recently blocks have come a little faster than that: the average over the last 144 blocks is 174.3 seconds.

Make a guess

Blocks 130,825 and 130,827 are 663 seconds apart. Does that mean block 130,826 took about 331 seconds?

Think of your answer first, then check it.

Answer Not necessarily.

Block times vary wildly, like any lottery. The two gaps could be anything that adds up to 663. (The chain data says the first gap was 646 seconds and the second only 17.) On 2026-10-20 the median gap over 100 blocks was just 94 seconds, while the mean was 165: a few long waits pull the average up.

Where else does time matter?

  • In the mining puzzle. The timestamp is one of the first 76 header bytes that are hashed into the job key. A new timestamp means new noise and new tickets, a fresh job. Pearl’s toy miner gets new jobs exactly this way.
  • In lock times. The median time past of the last 11 blocks is still computed, and it still decides when time-locked transactions become valid (BIP 113 and relative lock times), exactly as in Bitcoin. Only the block-timestamp rule changed.
Code: the two checks

The lower bound, from validate.go (node/blockchain/validate.go:686-696 at v1.5.2, on GitHub):

node/blockchain/validate.go Go
// Enforce strict timestamp monotonicity: each block's timestamp
// must be at least MinTimestampDelta seconds after the previous block.
// This is stricter than the original median-time rule and makes the
// median time check redundant. Required for WTEMA difficulty adjustment.
prevTimestamp := time.Unix(prevNode.Timestamp(), 0)
minTimestamp := prevTimestamp.Add(time.Duration(MinTimestampDeltaSeconds) * time.Second)
if header.Timestamp.Before(minTimestamp) {
	return ruleError(ErrTimeTooOld, str)
}

The upper bound, from validate.go (node/blockchain/validate.go:390-396 at v1.5.2, on GitHub), with MaxTimeOffsetMinutes: 5 set in params.go (node/chaincfg/params.go:357-362 at v1.5.2, on GitHub):

node/blockchain/validate.go Go
maxTimestamp := timeSource.AdjustedTime().Add(time.Minute * time.Duration(maxTimeOffsetMinutes))
if header.Timestamp.After(maxTimestamp) {
	return ruleError(ErrTimeTooNew, str)
}

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.